").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- }).complete( callback && function( jqXHR, status ) {
- self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
- });
- }
-
- return this;
-};
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
-};
-
-
-
-
-
-var docElem = window.document.documentElement;
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ?
- elem :
- elem.nodeType === 9 ?
- elem.defaultView || elem.parentWindow :
- false;
-}
-
-jQuery.offset = {
- setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
-
- // set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) &&
- jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
-
- // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
- } else {
- curElem.css( props );
- }
- }
-};
-
-jQuery.fn.extend({
- offset: function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- var docElem, win,
- box = { top: 0, left: 0 },
- elem = this[ 0 ],
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- // If we don't have gBCR, just use 0,0 rather than error
- // BlackBerry 5, iOS 3 (original iPhone)
- if ( typeof elem.getBoundingClientRect !== strundefined ) {
- box = elem.getBoundingClientRect();
- }
- win = getWindow( doc );
- return {
- top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
- left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
- };
- },
-
- position: function() {
- if ( !this[ 0 ] ) {
- return;
- }
-
- var offsetParent, offset,
- parentOffset = { top: 0, left: 0 },
- elem = this[ 0 ];
-
- // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
- // we assume that getBoundingClientRect is available when computed position is fixed
- offset = elem.getBoundingClientRect();
- } else {
- // Get *real* offsetParent
- offsetParent = this.offsetParent();
-
- // Get correct offsets
- offset = this.offset();
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
- parentOffset = offsetParent.offset();
- }
-
- // Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
- }
-
- // Subtract parent offsets and element margins
- // note: when an element has margin: auto the offsetLeft and marginLeft
- // are the same in Safari causing offset.left to incorrectly be 0
- return {
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || docElem;
-
- while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent || docElem;
- });
- }
-});
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
- var top = /Y/.test( prop );
-
- jQuery.fn[ method ] = function( val ) {
- return access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? (prop in win) ? win[ prop ] :
- win.document.documentElement[ method ] :
- elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : jQuery( win ).scrollLeft(),
- top ? val : jQuery( win ).scrollTop()
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length, null );
- };
-});
-
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// getComputedStyle returns percent when specified for top/left/bottom/right
-// rather than make the css module depend on the offset module, we just check for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
- function( elem, computed ) {
- if ( computed ) {
- computed = curCSS( elem, prop );
- // if curCSS returns percentage, fallback to offset
- return rnumnonpx.test( computed ) ?
- jQuery( elem ).position()[ prop ] + "px" :
- computed;
- }
- }
- );
-});
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
- // margin is only for outerHeight, outerWidth
- jQuery.fn[ funcName ] = function( margin, value ) {
- var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
- extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
- return access( this, function( elem, type, value ) {
- var doc;
-
- if ( jQuery.isWindow( elem ) ) {
- // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
- // isn't a whole lot we can do. See pull request at this URL for discussion:
- // https://github.com/jquery/jquery/pull/764
- return elem.document.documentElement[ "client" + name ];
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- doc = elem.documentElement;
-
- // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
- // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
- return Math.max(
- elem.body[ "scroll" + name ], doc[ "scroll" + name ],
- elem.body[ "offset" + name ], doc[ "offset" + name ],
- doc[ "client" + name ]
- );
- }
-
- return value === undefined ?
- // Get width or height on the element, requesting but not forcing parseFloat
- jQuery.css( elem, type, extra ) :
-
- // Set width or height on the element
- jQuery.style( elem, type, value, extra );
- }, type, chainable ? margin : undefined, chainable, null );
- };
- });
-});
-
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
- return this.length;
-};
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function() {
- return jQuery;
- });
-}
-
-
-
-
-var
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$;
-
-jQuery.noConflict = function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in
-// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === strundefined ) {
- window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-
-}));
diff --git a/docs/build/html/_static/jquery.js b/docs/build/html/_static/jquery.js
deleted file mode 100644
index ab28a2472..000000000
--- a/docs/build/html/_static/jquery.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="
",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d
b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
-if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,""],area:[1,""],param:[1,""],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
-},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/docs/build/html/_static/js/modernizr.min.js b/docs/build/html/_static/js/modernizr.min.js
deleted file mode 100644
index f65d47974..000000000
--- a/docs/build/html/_static/js/modernizr.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
- */
-;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f
");
-
- // Add expand links to all parents of nested ul
- $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
- var link = $(this);
- expand = $('');
- expand.on('click', function (ev) {
- self.toggleCurrent(link);
- ev.stopPropagation();
- return false;
- });
- link.prepend(expand);
- });
- };
-
- nav.reset = function () {
- // Get anchor from URL and open up nested nav
- var anchor = encodeURI(window.location.hash);
- if (anchor) {
- try {
- var link = $('.wy-menu-vertical')
- .find('[href="' + anchor + '"]');
- $('.wy-menu-vertical li.toctree-l1 li.current')
- .removeClass('current');
- link.closest('li.toctree-l2').addClass('current');
- link.closest('li.toctree-l3').addClass('current');
- link.closest('li.toctree-l4').addClass('current');
- }
- catch (err) {
- console.log("Error expanding nav for anchor", err);
- }
- }
- };
-
- nav.onScroll = function () {
- this.winScroll = false;
- var newWinPosition = this.win.scrollTop(),
- winBottom = newWinPosition + this.winHeight,
- navPosition = this.navBar.scrollTop(),
- newNavPosition = navPosition + (newWinPosition - this.winPosition);
- if (newWinPosition < 0 || winBottom > this.docHeight) {
- return;
- }
- this.navBar.scrollTop(newNavPosition);
- this.winPosition = newWinPosition;
- };
-
- nav.onResize = function () {
- this.winResize = false;
- this.winHeight = this.win.height();
- this.docHeight = $(document).height();
- };
-
- nav.hashChange = function () {
- this.linkScroll = true;
- this.win.one('hashchange', function () {
- this.linkScroll = false;
- });
- };
-
- nav.toggleCurrent = function (elem) {
- var parent_li = elem.closest('li');
- parent_li.siblings('li.current').removeClass('current');
- parent_li.siblings().find('li.current').removeClass('current');
- parent_li.find('> ul li.current').removeClass('current');
- parent_li.toggleClass('current');
- }
-
- return nav;
-};
-
-module.exports.ThemeNav = ThemeNav();
-
-if (typeof(window) != 'undefined') {
- window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
-}
-
-},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);
diff --git a/docs/build/html/_static/minus.png b/docs/build/html/_static/minus.png
deleted file mode 100644
index 0f22b16b0..000000000
Binary files a/docs/build/html/_static/minus.png and /dev/null differ
diff --git a/docs/build/html/_static/plus.png b/docs/build/html/_static/plus.png
deleted file mode 100644
index 0cfe084cf..000000000
Binary files a/docs/build/html/_static/plus.png and /dev/null differ
diff --git a/docs/build/html/_static/pygments.css b/docs/build/html/_static/pygments.css
deleted file mode 100644
index 8213e90be..000000000
--- a/docs/build/html/_static/pygments.css
+++ /dev/null
@@ -1,65 +0,0 @@
-.highlight .hll { background-color: #ffffcc }
-.highlight { background: #eeffcc; }
-.highlight .c { color: #408090; font-style: italic } /* Comment */
-.highlight .err { border: 1px solid #FF0000 } /* Error */
-.highlight .k { color: #007020; font-weight: bold } /* Keyword */
-.highlight .o { color: #666666 } /* Operator */
-.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
-.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #007020 } /* Comment.Preproc */
-.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
-.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
-.highlight .gd { color: #A00000 } /* Generic.Deleted */
-.highlight .ge { font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #FF0000 } /* Generic.Error */
-.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #333333 } /* Generic.Output */
-.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
-.highlight .gs { font-weight: bold } /* Generic.Strong */
-.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
-.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
-.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
-.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
-.highlight .kp { color: #007020 } /* Keyword.Pseudo */
-.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
-.highlight .kt { color: #902000 } /* Keyword.Type */
-.highlight .m { color: #208050 } /* Literal.Number */
-.highlight .s { color: #4070a0 } /* Literal.String */
-.highlight .na { color: #4070a0 } /* Name.Attribute */
-.highlight .nb { color: #007020 } /* Name.Builtin */
-.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.highlight .no { color: #60add5 } /* Name.Constant */
-.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
-.highlight .ne { color: #007020 } /* Name.Exception */
-.highlight .nf { color: #06287e } /* Name.Function */
-.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
-.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
-.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #bb60d5 } /* Name.Variable */
-.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.highlight .w { color: #bbbbbb } /* Text.Whitespace */
-.highlight .mb { color: #208050 } /* Literal.Number.Bin */
-.highlight .mf { color: #208050 } /* Literal.Number.Float */
-.highlight .mh { color: #208050 } /* Literal.Number.Hex */
-.highlight .mi { color: #208050 } /* Literal.Number.Integer */
-.highlight .mo { color: #208050 } /* Literal.Number.Oct */
-.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
-.highlight .sc { color: #4070a0 } /* Literal.String.Char */
-.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
-.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.highlight .sx { color: #c65d09 } /* Literal.String.Other */
-.highlight .sr { color: #235388 } /* Literal.String.Regex */
-.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
-.highlight .ss { color: #517918 } /* Literal.String.Symbol */
-.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
-.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
-.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/docs/build/html/_static/searchtools.js b/docs/build/html/_static/searchtools.js
deleted file mode 100644
index a51e0dc5b..000000000
--- a/docs/build/html/_static/searchtools.js
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * searchtools.js_t
- * ~~~~~~~~~~~~~~~~
- *
- * Sphinx JavaScript utilities for the full-text search.
- *
- * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-
-/* Non-minified version JS is _stemmer.js if file is provided */
-/**
- * Porter Stemmer
- */
-var Stemmer = function() {
-
- var step2list = {
- ational: 'ate',
- tional: 'tion',
- enci: 'ence',
- anci: 'ance',
- izer: 'ize',
- bli: 'ble',
- alli: 'al',
- entli: 'ent',
- eli: 'e',
- ousli: 'ous',
- ization: 'ize',
- ation: 'ate',
- ator: 'ate',
- alism: 'al',
- iveness: 'ive',
- fulness: 'ful',
- ousness: 'ous',
- aliti: 'al',
- iviti: 'ive',
- biliti: 'ble',
- logi: 'log'
- };
-
- var step3list = {
- icate: 'ic',
- ative: '',
- alize: 'al',
- iciti: 'ic',
- ical: 'ic',
- ful: '',
- ness: ''
- };
-
- var c = "[^aeiou]"; // consonant
- var v = "[aeiouy]"; // vowel
- var C = c + "[^aeiouy]*"; // consonant sequence
- var V = v + "[aeiou]*"; // vowel sequence
-
- var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
- var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
- var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
- var s_v = "^(" + C + ")?" + v; // vowel in stem
-
- this.stemWord = function (w) {
- var stem;
- var suffix;
- var firstch;
- var origword = w;
-
- if (w.length < 3)
- return w;
-
- var re;
- var re2;
- var re3;
- var re4;
-
- firstch = w.substr(0,1);
- if (firstch == "y")
- w = firstch.toUpperCase() + w.substr(1);
-
- // Step 1a
- re = /^(.+?)(ss|i)es$/;
- re2 = /^(.+?)([^s])s$/;
-
- if (re.test(w))
- w = w.replace(re,"$1$2");
- else if (re2.test(w))
- w = w.replace(re2,"$1$2");
-
- // Step 1b
- re = /^(.+?)eed$/;
- re2 = /^(.+?)(ed|ing)$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- re = new RegExp(mgr0);
- if (re.test(fp[1])) {
- re = /.$/;
- w = w.replace(re,"");
- }
- }
- else if (re2.test(w)) {
- var fp = re2.exec(w);
- stem = fp[1];
- re2 = new RegExp(s_v);
- if (re2.test(stem)) {
- w = stem;
- re2 = /(at|bl|iz)$/;
- re3 = new RegExp("([^aeiouylsz])\\1$");
- re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
- if (re2.test(w))
- w = w + "e";
- else if (re3.test(w)) {
- re = /.$/;
- w = w.replace(re,"");
- }
- else if (re4.test(w))
- w = w + "e";
- }
- }
-
- // Step 1c
- re = /^(.+?)y$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- stem = fp[1];
- re = new RegExp(s_v);
- if (re.test(stem))
- w = stem + "i";
- }
-
- // Step 2
- re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- stem = fp[1];
- suffix = fp[2];
- re = new RegExp(mgr0);
- if (re.test(stem))
- w = stem + step2list[suffix];
- }
-
- // Step 3
- re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- stem = fp[1];
- suffix = fp[2];
- re = new RegExp(mgr0);
- if (re.test(stem))
- w = stem + step3list[suffix];
- }
-
- // Step 4
- re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
- re2 = /^(.+?)(s|t)(ion)$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- stem = fp[1];
- re = new RegExp(mgr1);
- if (re.test(stem))
- w = stem;
- }
- else if (re2.test(w)) {
- var fp = re2.exec(w);
- stem = fp[1] + fp[2];
- re2 = new RegExp(mgr1);
- if (re2.test(stem))
- w = stem;
- }
-
- // Step 5
- re = /^(.+?)e$/;
- if (re.test(w)) {
- var fp = re.exec(w);
- stem = fp[1];
- re = new RegExp(mgr1);
- re2 = new RegExp(meq1);
- re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
- if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
- w = stem;
- }
- re = /ll$/;
- re2 = new RegExp(mgr1);
- if (re.test(w) && re2.test(w)) {
- re = /.$/;
- w = w.replace(re,"");
- }
-
- // and turn initial Y back to y
- if (firstch == "y")
- w = firstch.toLowerCase() + w.substr(1);
- return w;
- }
-}
-
-
-
-/**
- * Simple result scoring code.
- */
-var Scorer = {
- // Implement the following function to further tweak the score for each result
- // The function takes a result array [filename, title, anchor, descr, score]
- // and returns the new score.
- /*
- score: function(result) {
- return result[4];
- },
- */
-
- // query matches the full name of an object
- objNameMatch: 11,
- // or matches in the last dotted part of the object name
- objPartialMatch: 6,
- // Additive scores depending on the priority of the object
- objPrio: {0: 15, // used to be importantResults
- 1: 5, // used to be objectResults
- 2: -5}, // used to be unimportantResults
- // Used when the priority is not in the mapping.
- objPrioDefault: 0,
-
- // query found in title
- title: 15,
- // query found in terms
- term: 5
-};
-
-
-/**
- * Search Module
- */
-var Search = {
-
- _index : null,
- _queued_query : null,
- _pulse_status : -1,
-
- init : function() {
- var params = $.getQueryParameters();
- if (params.q) {
- var query = params.q[0];
- $('input[name="q"]')[0].value = query;
- this.performSearch(query);
- }
- },
-
- loadIndex : function(url) {
- $.ajax({type: "GET", url: url, data: null,
- dataType: "script", cache: true,
- complete: function(jqxhr, textstatus) {
- if (textstatus != "success") {
- document.getElementById("searchindexloader").src = url;
- }
- }});
- },
-
- setIndex : function(index) {
- var q;
- this._index = index;
- if ((q = this._queued_query) !== null) {
- this._queued_query = null;
- Search.query(q);
- }
- },
-
- hasIndex : function() {
- return this._index !== null;
- },
-
- deferQuery : function(query) {
- this._queued_query = query;
- },
-
- stopPulse : function() {
- this._pulse_status = 0;
- },
-
- startPulse : function() {
- if (this._pulse_status >= 0)
- return;
- function pulse() {
- var i;
- Search._pulse_status = (Search._pulse_status + 1) % 4;
- var dotString = '';
- for (i = 0; i < Search._pulse_status; i++)
- dotString += '.';
- Search.dots.text(dotString);
- if (Search._pulse_status > -1)
- window.setTimeout(pulse, 500);
- }
- pulse();
- },
-
- /**
- * perform a search for something (or wait until index is loaded)
- */
- performSearch : function(query) {
- // create the required interface elements
- this.out = $('#search-results');
- this.title = $('' + _('Searching') + '
').appendTo(this.out);
- this.dots = $('').appendTo(this.title);
- this.status = $('').appendTo(this.out);
- this.output = $('').appendTo(this.out);
-
- $('#search-progress').text(_('Preparing search...'));
- this.startPulse();
-
- // index already loaded, the browser was quick!
- if (this.hasIndex())
- this.query(query);
- else
- this.deferQuery(query);
- },
-
- /**
- * execute search (requires search index to be loaded)
- */
- query : function(query) {
- var i;
- var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
-
- // stem the searchterms and add them to the correct list
- var stemmer = new Stemmer();
- var searchterms = [];
- var excluded = [];
- var hlterms = [];
- var tmp = query.split(/\W+/);
- var objectterms = [];
- for (i = 0; i < tmp.length; i++) {
- if (tmp[i] !== "") {
- objectterms.push(tmp[i].toLowerCase());
- }
-
- if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
- tmp[i] === "") {
- // skip this "word"
- continue;
- }
- // stem the word
- var word = stemmer.stemWord(tmp[i].toLowerCase());
- var toAppend;
- // select the correct list
- if (word[0] == '-') {
- toAppend = excluded;
- word = word.substr(1);
- }
- else {
- toAppend = searchterms;
- hlterms.push(tmp[i].toLowerCase());
- }
- // only add if not already in the list
- if (!$u.contains(toAppend, word))
- toAppend.push(word);
- }
- var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
-
- // console.debug('SEARCH: searching for:');
- // console.info('required: ', searchterms);
- // console.info('excluded: ', excluded);
-
- // prepare search
- var terms = this._index.terms;
- var titleterms = this._index.titleterms;
-
- // array of [filename, title, anchor, descr, score]
- var results = [];
- $('#search-progress').empty();
-
- // lookup as object
- for (i = 0; i < objectterms.length; i++) {
- var others = [].concat(objectterms.slice(0, i),
- objectterms.slice(i+1, objectterms.length));
- results = results.concat(this.performObjectSearch(objectterms[i], others));
- }
-
- // lookup as search terms in fulltext
- results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
-
- // let the scorer override scores with a custom scoring function
- if (Scorer.score) {
- for (i = 0; i < results.length; i++)
- results[i][4] = Scorer.score(results[i]);
- }
-
- // now sort the results by score (in opposite order of appearance, since the
- // display function below uses pop() to retrieve items) and then
- // alphabetically
- results.sort(function(a, b) {
- var left = a[4];
- var right = b[4];
- if (left > right) {
- return 1;
- } else if (left < right) {
- return -1;
- } else {
- // same score: sort alphabetically
- left = a[1].toLowerCase();
- right = b[1].toLowerCase();
- return (left > right) ? -1 : ((left < right) ? 1 : 0);
- }
- });
-
- // for debugging
- //Search.lastresults = results.slice(); // a copy
- //console.info('search results:', Search.lastresults);
-
- // print the results
- var resultCount = results.length;
- function displayNextItem() {
- // results left, load the summary and display it
- if (results.length) {
- var item = results.pop();
- var listItem = $('');
- if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
- // dirhtml builder
- var dirname = item[0] + '/';
- if (dirname.match(/\/index\/$/)) {
- dirname = dirname.substring(0, dirname.length-6);
- } else if (dirname == 'index/') {
- dirname = '';
- }
- listItem.append($('').attr('href',
- DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
- highlightstring + item[2]).html(item[1]));
- } else {
- // normal html builders
- listItem.append($('').attr('href',
- item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
- highlightstring + item[2]).html(item[1]));
- }
- if (item[3]) {
- listItem.append($(' (' + item[3] + ')'));
- Search.output.append(listItem);
- listItem.slideDown(5, function() {
- displayNextItem();
- });
- } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
- $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
- dataType: "text",
- complete: function(jqxhr, textstatus) {
- var data = jqxhr.responseText;
- if (data !== '' && data !== undefined) {
- listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
- }
- Search.output.append(listItem);
- listItem.slideDown(5, function() {
- displayNextItem();
- });
- }});
- } else {
- // no source available, just display title
- Search.output.append(listItem);
- listItem.slideDown(5, function() {
- displayNextItem();
- });
- }
- }
- // search finished, update title and status message
- else {
- Search.stopPulse();
- Search.title.text(_('Search Results'));
- if (!resultCount)
- Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
- else
- Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
- Search.status.fadeIn(500);
- }
- }
- displayNextItem();
- },
-
- /**
- * search for object names
- */
- performObjectSearch : function(object, otherterms) {
- var filenames = this._index.filenames;
- var objects = this._index.objects;
- var objnames = this._index.objnames;
- var titles = this._index.titles;
-
- var i;
- var results = [];
-
- for (var prefix in objects) {
- for (var name in objects[prefix]) {
- var fullname = (prefix ? prefix + '.' : '') + name;
- if (fullname.toLowerCase().indexOf(object) > -1) {
- var score = 0;
- var parts = fullname.split('.');
- // check for different match types: exact matches of full name or
- // "last name" (i.e. last dotted part)
- if (fullname == object || parts[parts.length - 1] == object) {
- score += Scorer.objNameMatch;
- // matches in last name
- } else if (parts[parts.length - 1].indexOf(object) > -1) {
- score += Scorer.objPartialMatch;
- }
- var match = objects[prefix][name];
- var objname = objnames[match[1]][2];
- var title = titles[match[0]];
- // If more than one term searched for, we require other words to be
- // found in the name/title/description
- if (otherterms.length > 0) {
- var haystack = (prefix + ' ' + name + ' ' +
- objname + ' ' + title).toLowerCase();
- var allfound = true;
- for (i = 0; i < otherterms.length; i++) {
- if (haystack.indexOf(otherterms[i]) == -1) {
- allfound = false;
- break;
- }
- }
- if (!allfound) {
- continue;
- }
- }
- var descr = objname + _(', in ') + title;
-
- var anchor = match[3];
- if (anchor === '')
- anchor = fullname;
- else if (anchor == '-')
- anchor = objnames[match[1]][1] + '-' + fullname;
- // add custom score for some objects according to scorer
- if (Scorer.objPrio.hasOwnProperty(match[2])) {
- score += Scorer.objPrio[match[2]];
- } else {
- score += Scorer.objPrioDefault;
- }
- results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
- }
- }
- }
-
- return results;
- },
-
- /**
- * search for full-text terms in the index
- */
- performTermsSearch : function(searchterms, excluded, terms, titleterms) {
- var filenames = this._index.filenames;
- var titles = this._index.titles;
-
- var i, j, file;
- var fileMap = {};
- var scoreMap = {};
- var results = [];
-
- // perform the search on the required terms
- for (i = 0; i < searchterms.length; i++) {
- var word = searchterms[i];
- var files = [];
- var _o = [
- {files: terms[word], score: Scorer.term},
- {files: titleterms[word], score: Scorer.title}
- ];
-
- // no match but word was a required one
- if ($u.every(_o, function(o){return o.files === undefined;})) {
- break;
- }
- // found search word in contents
- $u.each(_o, function(o) {
- var _files = o.files;
- if (_files === undefined)
- return
-
- if (_files.length === undefined)
- _files = [_files];
- files = files.concat(_files);
-
- // set score for the word in each file to Scorer.term
- for (j = 0; j < _files.length; j++) {
- file = _files[j];
- if (!(file in scoreMap))
- scoreMap[file] = {}
- scoreMap[file][word] = o.score;
- }
- });
-
- // create the mapping
- for (j = 0; j < files.length; j++) {
- file = files[j];
- if (file in fileMap)
- fileMap[file].push(word);
- else
- fileMap[file] = [word];
- }
- }
-
- // now check if the files don't contain excluded terms
- for (file in fileMap) {
- var valid = true;
-
- // check if all requirements are matched
- if (fileMap[file].length != searchterms.length)
- continue;
-
- // ensure that none of the excluded terms is in the search result
- for (i = 0; i < excluded.length; i++) {
- if (terms[excluded[i]] == file ||
- titleterms[excluded[i]] == file ||
- $u.contains(terms[excluded[i]] || [], file) ||
- $u.contains(titleterms[excluded[i]] || [], file)) {
- valid = false;
- break;
- }
- }
-
- // if we have still a valid result we can add it to the result list
- if (valid) {
- // select one (max) score for the file.
- // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
- var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
- results.push([filenames[file], titles[file], '', null, score]);
- }
- }
- return results;
- },
-
- /**
- * helper function to return a node containing the
- * search summary for a given text. keywords is a list
- * of stemmed words, hlwords is the list of normal, unstemmed
- * words. the first one is used to find the occurrence, the
- * latter for highlighting it.
- */
- makeSearchSummary : function(text, keywords, hlwords) {
- var textLower = text.toLowerCase();
- var start = 0;
- $.each(keywords, function() {
- var i = textLower.indexOf(this.toLowerCase());
- if (i > -1)
- start = i;
- });
- start = Math.max(start - 120, 0);
- var excerpt = ((start > 0) ? '...' : '') +
- $.trim(text.substr(start, 240)) +
- ((start + 240 - text.length) ? '...' : '');
- var rv = $('').text(excerpt);
- $.each(hlwords, function() {
- rv = rv.highlightText(this, 'highlighted');
- });
- return rv;
- }
-};
-
-$(document).ready(function() {
- Search.init();
-});
\ No newline at end of file
diff --git a/docs/build/html/_static/underscore-1.3.1.js b/docs/build/html/_static/underscore-1.3.1.js
deleted file mode 100644
index 208d4cd89..000000000
--- a/docs/build/html/_static/underscore-1.3.1.js
+++ /dev/null
@@ -1,999 +0,0 @@
-// Underscore.js 1.3.1
-// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-
-(function() {
-
- // Baseline setup
- // --------------
-
- // Establish the root object, `window` in the browser, or `global` on the server.
- var root = this;
-
- // Save the previous value of the `_` variable.
- var previousUnderscore = root._;
-
- // Establish the object that gets returned to break out of a loop iteration.
- var breaker = {};
-
- // Save bytes in the minified (but not gzipped) version:
- var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
-
- // Create quick reference variables for speed access to core prototypes.
- var slice = ArrayProto.slice,
- unshift = ArrayProto.unshift,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty;
-
- // All **ECMAScript 5** native function implementations that we hope to use
- // are declared here.
- var
- nativeForEach = ArrayProto.forEach,
- nativeMap = ArrayProto.map,
- nativeReduce = ArrayProto.reduce,
- nativeReduceRight = ArrayProto.reduceRight,
- nativeFilter = ArrayProto.filter,
- nativeEvery = ArrayProto.every,
- nativeSome = ArrayProto.some,
- nativeIndexOf = ArrayProto.indexOf,
- nativeLastIndexOf = ArrayProto.lastIndexOf,
- nativeIsArray = Array.isArray,
- nativeKeys = Object.keys,
- nativeBind = FuncProto.bind;
-
- // Create a safe reference to the Underscore object for use below.
- var _ = function(obj) { return new wrapper(obj); };
-
- // Export the Underscore object for **Node.js**, with
- // backwards-compatibility for the old `require()` API. If we're in
- // the browser, add `_` as a global object via a string identifier,
- // for Closure Compiler "advanced" mode.
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
- exports = module.exports = _;
- }
- exports._ = _;
- } else {
- root['_'] = _;
- }
-
- // Current version.
- _.VERSION = '1.3.1';
-
- // Collection Functions
- // --------------------
-
- // The cornerstone, an `each` implementation, aka `forEach`.
- // Handles objects with the built-in `forEach`, arrays, and raw objects.
- // Delegates to **ECMAScript 5**'s native `forEach` if available.
- var each = _.each = _.forEach = function(obj, iterator, context) {
- if (obj == null) return;
- if (nativeForEach && obj.forEach === nativeForEach) {
- obj.forEach(iterator, context);
- } else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
- if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
- }
- } else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
- }
- }
- };
-
- // Return the results of applying the iterator to each element.
- // Delegates to **ECMAScript 5**'s native `map` if available.
- _.map = _.collect = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
- each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
- });
- if (obj.length === +obj.length) results.length = obj.length;
- return results;
- };
-
- // **Reduce** builds up a single result from a list of values, aka `inject`,
- // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
- _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduce && obj.reduce === nativeReduce) {
- if (context) iterator = _.bind(iterator, context);
- return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
- }
- each(obj, function(value, index, list) {
- if (!initial) {
- memo = value;
- initial = true;
- } else {
- memo = iterator.call(context, memo, value, index, list);
- }
- });
- if (!initial) throw new TypeError('Reduce of empty array with no initial value');
- return memo;
- };
-
- // The right-associative version of reduce, also known as `foldr`.
- // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
- _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
- if (context) iterator = _.bind(iterator, context);
- return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
- }
- var reversed = _.toArray(obj).reverse();
- if (context && !initial) iterator = _.bind(iterator, context);
- return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
- };
-
- // Return the first value which passes a truth test. Aliased as `detect`.
- _.find = _.detect = function(obj, iterator, context) {
- var result;
- any(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) {
- result = value;
- return true;
- }
- });
- return result;
- };
-
- // Return all the elements that pass a truth test.
- // Delegates to **ECMAScript 5**'s native `filter` if available.
- // Aliased as `select`.
- _.filter = _.select = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
- each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
- };
-
- // Return all the elements for which a truth test fails.
- _.reject = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- each(obj, function(value, index, list) {
- if (!iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
- };
-
- // Determine whether all of the elements match a truth test.
- // Delegates to **ECMAScript 5**'s native `every` if available.
- // Aliased as `all`.
- _.every = _.all = function(obj, iterator, context) {
- var result = true;
- if (obj == null) return result;
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
- each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
- });
- return result;
- };
-
- // Determine if at least one element in the object matches a truth test.
- // Delegates to **ECMAScript 5**'s native `some` if available.
- // Aliased as `any`.
- var any = _.some = _.any = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
- var result = false;
- if (obj == null) return result;
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
- each(obj, function(value, index, list) {
- if (result || (result = iterator.call(context, value, index, list))) return breaker;
- });
- return !!result;
- };
-
- // Determine if a given value is included in the array or object using `===`.
- // Aliased as `contains`.
- _.include = _.contains = function(obj, target) {
- var found = false;
- if (obj == null) return found;
- if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
- found = any(obj, function(value) {
- return value === target;
- });
- return found;
- };
-
- // Invoke a method (with arguments) on every item in a collection.
- _.invoke = function(obj, method) {
- var args = slice.call(arguments, 2);
- return _.map(obj, function(value) {
- return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
- });
- };
-
- // Convenience version of a common use case of `map`: fetching a property.
- _.pluck = function(obj, key) {
- return _.map(obj, function(value){ return value[key]; });
- };
-
- // Return the maximum element or (element-based computation).
- _.max = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
- if (!iterator && _.isEmpty(obj)) return -Infinity;
- var result = {computed : -Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed >= result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- };
-
- // Return the minimum element (or element-based computation).
- _.min = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
- if (!iterator && _.isEmpty(obj)) return Infinity;
- var result = {computed : Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed < result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- };
-
- // Shuffle an array.
- _.shuffle = function(obj) {
- var shuffled = [], rand;
- each(obj, function(value, index, list) {
- if (index == 0) {
- shuffled[0] = value;
- } else {
- rand = Math.floor(Math.random() * (index + 1));
- shuffled[index] = shuffled[rand];
- shuffled[rand] = value;
- }
- });
- return shuffled;
- };
-
- // Sort the object's values by a criterion produced by an iterator.
- _.sortBy = function(obj, iterator, context) {
- return _.pluck(_.map(obj, function(value, index, list) {
- return {
- value : value,
- criteria : iterator.call(context, value, index, list)
- };
- }).sort(function(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }), 'value');
- };
-
- // Groups the object's values by a criterion. Pass either a string attribute
- // to group by, or a function that returns the criterion.
- _.groupBy = function(obj, val) {
- var result = {};
- var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
- each(obj, function(value, index) {
- var key = iterator(value, index);
- (result[key] || (result[key] = [])).push(value);
- });
- return result;
- };
-
- // Use a comparator function to figure out at what index an object should
- // be inserted so as to maintain order. Uses binary search.
- _.sortedIndex = function(array, obj, iterator) {
- iterator || (iterator = _.identity);
- var low = 0, high = array.length;
- while (low < high) {
- var mid = (low + high) >> 1;
- iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
- }
- return low;
- };
-
- // Safely convert anything iterable into a real, live array.
- _.toArray = function(iterable) {
- if (!iterable) return [];
- if (iterable.toArray) return iterable.toArray();
- if (_.isArray(iterable)) return slice.call(iterable);
- if (_.isArguments(iterable)) return slice.call(iterable);
- return _.values(iterable);
- };
-
- // Return the number of elements in an object.
- _.size = function(obj) {
- return _.toArray(obj).length;
- };
-
- // Array Functions
- // ---------------
-
- // Get the first element of an array. Passing **n** will return the first N
- // values in the array. Aliased as `head`. The **guard** check allows it to work
- // with `_.map`.
- _.first = _.head = function(array, n, guard) {
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
- };
-
- // Returns everything but the last entry of the array. Especcialy useful on
- // the arguments object. Passing **n** will return all the values in
- // the array, excluding the last N. The **guard** check allows it to work with
- // `_.map`.
- _.initial = function(array, n, guard) {
- return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
- };
-
- // Get the last element of an array. Passing **n** will return the last N
- // values in the array. The **guard** check allows it to work with `_.map`.
- _.last = function(array, n, guard) {
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
- return array[array.length - 1];
- }
- };
-
- // Returns everything but the first entry of the array. Aliased as `tail`.
- // Especially useful on the arguments object. Passing an **index** will return
- // the rest of the values in the array from that index onward. The **guard**
- // check allows it to work with `_.map`.
- _.rest = _.tail = function(array, index, guard) {
- return slice.call(array, (index == null) || guard ? 1 : index);
- };
-
- // Trim out all falsy values from an array.
- _.compact = function(array) {
- return _.filter(array, function(value){ return !!value; });
- };
-
- // Return a completely flattened version of an array.
- _.flatten = function(array, shallow) {
- return _.reduce(array, function(memo, value) {
- if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
- memo[memo.length] = value;
- return memo;
- }, []);
- };
-
- // Return a version of the array that does not contain the specified value(s).
- _.without = function(array) {
- return _.difference(array, slice.call(arguments, 1));
- };
-
- // Produce a duplicate-free version of the array. If the array has already
- // been sorted, you have the option of using a faster algorithm.
- // Aliased as `unique`.
- _.uniq = _.unique = function(array, isSorted, iterator) {
- var initial = iterator ? _.map(array, iterator) : array;
- var result = [];
- _.reduce(initial, function(memo, el, i) {
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
- memo[memo.length] = el;
- result[result.length] = array[i];
- }
- return memo;
- }, []);
- return result;
- };
-
- // Produce an array that contains the union: each distinct element from all of
- // the passed-in arrays.
- _.union = function() {
- return _.uniq(_.flatten(arguments, true));
- };
-
- // Produce an array that contains every item shared between all the
- // passed-in arrays. (Aliased as "intersect" for back-compat.)
- _.intersection = _.intersect = function(array) {
- var rest = slice.call(arguments, 1);
- return _.filter(_.uniq(array), function(item) {
- return _.every(rest, function(other) {
- return _.indexOf(other, item) >= 0;
- });
- });
- };
-
- // Take the difference between one array and a number of other arrays.
- // Only the elements present in just the first array will remain.
- _.difference = function(array) {
- var rest = _.flatten(slice.call(arguments, 1));
- return _.filter(array, function(value){ return !_.include(rest, value); });
- };
-
- // Zip together multiple lists into a single array -- elements that share
- // an index go together.
- _.zip = function() {
- var args = slice.call(arguments);
- var length = _.max(_.pluck(args, 'length'));
- var results = new Array(length);
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
- return results;
- };
-
- // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
- // we need this function. Return the position of the first occurrence of an
- // item in an array, or -1 if the item is not included in the array.
- // Delegates to **ECMAScript 5**'s native `indexOf` if available.
- // If the array is large and already in sort order, pass `true`
- // for **isSorted** to use binary search.
- _.indexOf = function(array, item, isSorted) {
- if (array == null) return -1;
- var i, l;
- if (isSorted) {
- i = _.sortedIndex(array, item);
- return array[i] === item ? i : -1;
- }
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
- for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
- return -1;
- };
-
- // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
- _.lastIndexOf = function(array, item) {
- if (array == null) return -1;
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
- var i = array.length;
- while (i--) if (i in array && array[i] === item) return i;
- return -1;
- };
-
- // Generate an integer Array containing an arithmetic progression. A port of
- // the native Python `range()` function. See
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
- _.range = function(start, stop, step) {
- if (arguments.length <= 1) {
- stop = start || 0;
- start = 0;
- }
- step = arguments[2] || 1;
-
- var len = Math.max(Math.ceil((stop - start) / step), 0);
- var idx = 0;
- var range = new Array(len);
-
- while(idx < len) {
- range[idx++] = start;
- start += step;
- }
-
- return range;
- };
-
- // Function (ahem) Functions
- // ------------------
-
- // Reusable constructor function for prototype setting.
- var ctor = function(){};
-
- // Create a function bound to a given object (assigning `this`, and arguments,
- // optionally). Binding with arguments is also known as `curry`.
- // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
- // We check for `func.bind` first, to fail fast when `func` is undefined.
- _.bind = function bind(func, context) {
- var bound, args;
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
- if (!_.isFunction(func)) throw new TypeError;
- args = slice.call(arguments, 2);
- return bound = function() {
- if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
- ctor.prototype = func.prototype;
- var self = new ctor;
- var result = func.apply(self, args.concat(slice.call(arguments)));
- if (Object(result) === result) return result;
- return self;
- };
- };
-
- // Bind all of an object's methods to that object. Useful for ensuring that
- // all callbacks defined on an object belong to it.
- _.bindAll = function(obj) {
- var funcs = slice.call(arguments, 1);
- if (funcs.length == 0) funcs = _.functions(obj);
- each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
- return obj;
- };
-
- // Memoize an expensive function by storing its results.
- _.memoize = function(func, hasher) {
- var memo = {};
- hasher || (hasher = _.identity);
- return function() {
- var key = hasher.apply(this, arguments);
- return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
- };
- };
-
- // Delays a function for the given number of milliseconds, and then calls
- // it with the arguments supplied.
- _.delay = function(func, wait) {
- var args = slice.call(arguments, 2);
- return setTimeout(function(){ return func.apply(func, args); }, wait);
- };
-
- // Defers a function, scheduling it to run after the current call stack has
- // cleared.
- _.defer = function(func) {
- return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
- };
-
- // Returns a function, that, when invoked, will only be triggered at most once
- // during a given window of time.
- _.throttle = function(func, wait) {
- var context, args, timeout, throttling, more;
- var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
- return function() {
- context = this; args = arguments;
- var later = function() {
- timeout = null;
- if (more) func.apply(context, args);
- whenDone();
- };
- if (!timeout) timeout = setTimeout(later, wait);
- if (throttling) {
- more = true;
- } else {
- func.apply(context, args);
- }
- whenDone();
- throttling = true;
- };
- };
-
- // Returns a function, that, as long as it continues to be invoked, will not
- // be triggered. The function will be called after it stops being called for
- // N milliseconds.
- _.debounce = function(func, wait) {
- var timeout;
- return function() {
- var context = this, args = arguments;
- var later = function() {
- timeout = null;
- func.apply(context, args);
- };
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- };
- };
-
- // Returns a function that will be executed at most one time, no matter how
- // often you call it. Useful for lazy initialization.
- _.once = function(func) {
- var ran = false, memo;
- return function() {
- if (ran) return memo;
- ran = true;
- return memo = func.apply(this, arguments);
- };
- };
-
- // Returns the first function passed as an argument to the second,
- // allowing you to adjust arguments, run code before and after, and
- // conditionally execute the original function.
- _.wrap = function(func, wrapper) {
- return function() {
- var args = [func].concat(slice.call(arguments, 0));
- return wrapper.apply(this, args);
- };
- };
-
- // Returns a function that is the composition of a list of functions, each
- // consuming the return value of the function that follows.
- _.compose = function() {
- var funcs = arguments;
- return function() {
- var args = arguments;
- for (var i = funcs.length - 1; i >= 0; i--) {
- args = [funcs[i].apply(this, args)];
- }
- return args[0];
- };
- };
-
- // Returns a function that will only be executed after being called N times.
- _.after = function(times, func) {
- if (times <= 0) return func();
- return function() {
- if (--times < 1) { return func.apply(this, arguments); }
- };
- };
-
- // Object Functions
- // ----------------
-
- // Retrieve the names of an object's properties.
- // Delegates to **ECMAScript 5**'s native `Object.keys`
- _.keys = nativeKeys || function(obj) {
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
- var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
- return keys;
- };
-
- // Retrieve the values of an object's properties.
- _.values = function(obj) {
- return _.map(obj, _.identity);
- };
-
- // Return a sorted list of the function names available on the object.
- // Aliased as `methods`
- _.functions = _.methods = function(obj) {
- var names = [];
- for (var key in obj) {
- if (_.isFunction(obj[key])) names.push(key);
- }
- return names.sort();
- };
-
- // Extend a given object with all the properties in passed-in object(s).
- _.extend = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- obj[prop] = source[prop];
- }
- });
- return obj;
- };
-
- // Fill in a given object with default properties.
- _.defaults = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
- }
- });
- return obj;
- };
-
- // Create a (shallow-cloned) duplicate of an object.
- _.clone = function(obj) {
- if (!_.isObject(obj)) return obj;
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
- };
-
- // Invokes interceptor with the obj, and then returns obj.
- // The primary purpose of this method is to "tap into" a method chain, in
- // order to perform operations on intermediate results within the chain.
- _.tap = function(obj, interceptor) {
- interceptor(obj);
- return obj;
- };
-
- // Internal recursive comparison function.
- function eq(a, b, stack) {
- // Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
- if (a === b) return a !== 0 || 1 / a == 1 / b;
- // A strict comparison is necessary because `null == undefined`.
- if (a == null || b == null) return a === b;
- // Unwrap any wrapped objects.
- if (a._chain) a = a._wrapped;
- if (b._chain) b = b._wrapped;
- // Invoke a custom `isEqual` method if one is provided.
- if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
- if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
- // Compare `[[Class]]` names.
- var className = toString.call(a);
- if (className != toString.call(b)) return false;
- switch (className) {
- // Strings, numbers, dates, and booleans are compared by value.
- case '[object String]':
- // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
- // equivalent to `new String("5")`.
- return a == String(b);
- case '[object Number]':
- // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
- // other numeric values.
- return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
- case '[object Date]':
- case '[object Boolean]':
- // Coerce dates and booleans to numeric primitive values. Dates are compared by their
- // millisecond representations. Note that invalid dates with millisecond representations
- // of `NaN` are not equivalent.
- return +a == +b;
- // RegExps are compared by their source patterns and flags.
- case '[object RegExp]':
- return a.source == b.source &&
- a.global == b.global &&
- a.multiline == b.multiline &&
- a.ignoreCase == b.ignoreCase;
- }
- if (typeof a != 'object' || typeof b != 'object') return false;
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
- var length = stack.length;
- while (length--) {
- // Linear search. Performance is inversely proportional to the number of
- // unique nested structures.
- if (stack[length] == a) return true;
- }
- // Add the first object to the stack of traversed objects.
- stack.push(a);
- var size = 0, result = true;
- // Recursively compare objects and arrays.
- if (className == '[object Array]') {
- // Compare array lengths to determine if a deep comparison is necessary.
- size = a.length;
- result = size == b.length;
- if (result) {
- // Deep compare the contents, ignoring non-numeric properties.
- while (size--) {
- // Ensure commutative equality for sparse arrays.
- if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
- }
- }
- } else {
- // Objects with different constructors are not equivalent.
- if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
- // Deep compare objects.
- for (var key in a) {
- if (_.has(a, key)) {
- // Count the expected number of properties.
- size++;
- // Deep compare each member.
- if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
- }
- }
- // Ensure that both objects contain the same number of properties.
- if (result) {
- for (key in b) {
- if (_.has(b, key) && !(size--)) break;
- }
- result = !size;
- }
- }
- // Remove the first object from the stack of traversed objects.
- stack.pop();
- return result;
- }
-
- // Perform a deep comparison to check if two objects are equal.
- _.isEqual = function(a, b) {
- return eq(a, b, []);
- };
-
- // Is a given array, string, or object empty?
- // An "empty" object has no enumerable own-properties.
- _.isEmpty = function(obj) {
- if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
- for (var key in obj) if (_.has(obj, key)) return false;
- return true;
- };
-
- // Is a given value a DOM element?
- _.isElement = function(obj) {
- return !!(obj && obj.nodeType == 1);
- };
-
- // Is a given value an array?
- // Delegates to ECMA5's native Array.isArray
- _.isArray = nativeIsArray || function(obj) {
- return toString.call(obj) == '[object Array]';
- };
-
- // Is a given variable an object?
- _.isObject = function(obj) {
- return obj === Object(obj);
- };
-
- // Is a given variable an arguments object?
- _.isArguments = function(obj) {
- return toString.call(obj) == '[object Arguments]';
- };
- if (!_.isArguments(arguments)) {
- _.isArguments = function(obj) {
- return !!(obj && _.has(obj, 'callee'));
- };
- }
-
- // Is a given value a function?
- _.isFunction = function(obj) {
- return toString.call(obj) == '[object Function]';
- };
-
- // Is a given value a string?
- _.isString = function(obj) {
- return toString.call(obj) == '[object String]';
- };
-
- // Is a given value a number?
- _.isNumber = function(obj) {
- return toString.call(obj) == '[object Number]';
- };
-
- // Is the given value `NaN`?
- _.isNaN = function(obj) {
- // `NaN` is the only value for which `===` is not reflexive.
- return obj !== obj;
- };
-
- // Is a given value a boolean?
- _.isBoolean = function(obj) {
- return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
- };
-
- // Is a given value a date?
- _.isDate = function(obj) {
- return toString.call(obj) == '[object Date]';
- };
-
- // Is the given value a regular expression?
- _.isRegExp = function(obj) {
- return toString.call(obj) == '[object RegExp]';
- };
-
- // Is a given value equal to null?
- _.isNull = function(obj) {
- return obj === null;
- };
-
- // Is a given variable undefined?
- _.isUndefined = function(obj) {
- return obj === void 0;
- };
-
- // Has own property?
- _.has = function(obj, key) {
- return hasOwnProperty.call(obj, key);
- };
-
- // Utility Functions
- // -----------------
-
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
- // previous owner. Returns a reference to the Underscore object.
- _.noConflict = function() {
- root._ = previousUnderscore;
- return this;
- };
-
- // Keep the identity function around for default iterators.
- _.identity = function(value) {
- return value;
- };
-
- // Run a function **n** times.
- _.times = function (n, iterator, context) {
- for (var i = 0; i < n; i++) iterator.call(context, i);
- };
-
- // Escape a string for HTML interpolation.
- _.escape = function(string) {
- return (''+string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
- };
-
- // Add your own custom functions to the Underscore object, ensuring that
- // they're correctly added to the OOP wrapper as well.
- _.mixin = function(obj) {
- each(_.functions(obj), function(name){
- addToWrapper(name, _[name] = obj[name]);
- });
- };
-
- // Generate a unique integer id (unique within the entire client session).
- // Useful for temporary DOM ids.
- var idCounter = 0;
- _.uniqueId = function(prefix) {
- var id = idCounter++;
- return prefix ? prefix + id : id;
- };
-
- // By default, Underscore uses ERB-style template delimiters, change the
- // following template settings to use alternative delimiters.
- _.templateSettings = {
- evaluate : /<%([\s\S]+?)%>/g,
- interpolate : /<%=([\s\S]+?)%>/g,
- escape : /<%-([\s\S]+?)%>/g
- };
-
- // When customizing `templateSettings`, if you don't want to define an
- // interpolation, evaluation or escaping regex, we need one that is
- // guaranteed not to match.
- var noMatch = /.^/;
-
- // Within an interpolation, evaluation, or escaping, remove HTML escaping
- // that had been previously added.
- var unescape = function(code) {
- return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'");
- };
-
- // JavaScript micro-templating, similar to John Resig's implementation.
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
- // and correctly escapes quotes within interpolated code.
- _.template = function(str, data) {
- var c = _.templateSettings;
- var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
- 'with(obj||{}){__p.push(\'' +
- str.replace(/\\/g, '\\\\')
- .replace(/'/g, "\\'")
- .replace(c.escape || noMatch, function(match, code) {
- return "',_.escape(" + unescape(code) + "),'";
- })
- .replace(c.interpolate || noMatch, function(match, code) {
- return "'," + unescape(code) + ",'";
- })
- .replace(c.evaluate || noMatch, function(match, code) {
- return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('";
- })
- .replace(/\r/g, '\\r')
- .replace(/\n/g, '\\n')
- .replace(/\t/g, '\\t')
- + "');}return __p.join('');";
- var func = new Function('obj', '_', tmpl);
- if (data) return func(data, _);
- return function(data) {
- return func.call(this, data, _);
- };
- };
-
- // Add a "chain" function, which will delegate to the wrapper.
- _.chain = function(obj) {
- return _(obj).chain();
- };
-
- // The OOP Wrapper
- // ---------------
-
- // If Underscore is called as a function, it returns a wrapped object that
- // can be used OO-style. This wrapper holds altered versions of all the
- // underscore functions. Wrapped objects may be chained.
- var wrapper = function(obj) { this._wrapped = obj; };
-
- // Expose `wrapper.prototype` as `_.prototype`
- _.prototype = wrapper.prototype;
-
- // Helper function to continue chaining intermediate results.
- var result = function(obj, chain) {
- return chain ? _(obj).chain() : obj;
- };
-
- // A method to easily add functions to the OOP wrapper.
- var addToWrapper = function(name, func) {
- wrapper.prototype[name] = function() {
- var args = slice.call(arguments);
- unshift.call(args, this._wrapped);
- return result(func.apply(_, args), this._chain);
- };
- };
-
- // Add all of the Underscore functions to the wrapper object.
- _.mixin(_);
-
- // Add all mutator Array functions to the wrapper.
- each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
- var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
- var wrapped = this._wrapped;
- method.apply(wrapped, arguments);
- var length = wrapped.length;
- if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
- return result(wrapped, this._chain);
- };
- });
-
- // Add all accessor Array functions to the wrapper.
- each(['concat', 'join', 'slice'], function(name) {
- var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
- return result(method.apply(this._wrapped, arguments), this._chain);
- };
- });
-
- // Start chaining a wrapped Underscore object.
- wrapper.prototype.chain = function() {
- this._chain = true;
- return this;
- };
-
- // Extracts the result from a wrapped and chained object.
- wrapper.prototype.value = function() {
- return this._wrapped;
- };
-
-}).call(this);
diff --git a/docs/build/html/_static/underscore.js b/docs/build/html/_static/underscore.js
deleted file mode 100644
index 5b55f32be..000000000
--- a/docs/build/html/_static/underscore.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Underscore.js 1.3.1
-// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
-h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
-b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==
-null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
-function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
-e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
-function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
-c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};
-b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
-1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
-b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
-b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
-function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
-u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
-function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
-true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
diff --git a/docs/build/html/_static/up-pressed.png b/docs/build/html/_static/up-pressed.png
deleted file mode 100644
index 99e721096..000000000
Binary files a/docs/build/html/_static/up-pressed.png and /dev/null differ
diff --git a/docs/build/html/_static/up.png b/docs/build/html/_static/up.png
deleted file mode 100644
index 26de002e8..000000000
Binary files a/docs/build/html/_static/up.png and /dev/null differ
diff --git a/docs/build/html/_static/websupport.js b/docs/build/html/_static/websupport.js
deleted file mode 100644
index 98e7f40b6..000000000
--- a/docs/build/html/_static/websupport.js
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * websupport.js
- * ~~~~~~~~~~~~~
- *
- * sphinx.websupport utilities for all documentation.
- *
- * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-(function($) {
- $.fn.autogrow = function() {
- return this.each(function() {
- var textarea = this;
-
- $.fn.autogrow.resize(textarea);
-
- $(textarea)
- .focus(function() {
- textarea.interval = setInterval(function() {
- $.fn.autogrow.resize(textarea);
- }, 500);
- })
- .blur(function() {
- clearInterval(textarea.interval);
- });
- });
- };
-
- $.fn.autogrow.resize = function(textarea) {
- var lineHeight = parseInt($(textarea).css('line-height'), 10);
- var lines = textarea.value.split('\n');
- var columns = textarea.cols;
- var lineCount = 0;
- $.each(lines, function() {
- lineCount += Math.ceil(this.length / columns) || 1;
- });
- var height = lineHeight * (lineCount + 1);
- $(textarea).css('height', height);
- };
-})(jQuery);
-
-(function($) {
- var comp, by;
-
- function init() {
- initEvents();
- initComparator();
- }
-
- function initEvents() {
- $(document).on("click", 'a.comment-close', function(event) {
- event.preventDefault();
- hide($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.vote', function(event) {
- event.preventDefault();
- handleVote($(this));
- });
- $(document).on("click", 'a.reply', function(event) {
- event.preventDefault();
- openReply($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.close-reply', function(event) {
- event.preventDefault();
- closeReply($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.sort-option', function(event) {
- event.preventDefault();
- handleReSort($(this));
- });
- $(document).on("click", 'a.show-proposal', function(event) {
- event.preventDefault();
- showProposal($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.hide-proposal', function(event) {
- event.preventDefault();
- hideProposal($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.show-propose-change', function(event) {
- event.preventDefault();
- showProposeChange($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.hide-propose-change', function(event) {
- event.preventDefault();
- hideProposeChange($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.accept-comment', function(event) {
- event.preventDefault();
- acceptComment($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.delete-comment', function(event) {
- event.preventDefault();
- deleteComment($(this).attr('id').substring(2));
- });
- $(document).on("click", 'a.comment-markup', function(event) {
- event.preventDefault();
- toggleCommentMarkupBox($(this).attr('id').substring(2));
- });
- }
-
- /**
- * Set comp, which is a comparator function used for sorting and
- * inserting comments into the list.
- */
- function setComparator() {
- // If the first three letters are "asc", sort in ascending order
- // and remove the prefix.
- if (by.substring(0,3) == 'asc') {
- var i = by.substring(3);
- comp = function(a, b) { return a[i] - b[i]; };
- } else {
- // Otherwise sort in descending order.
- comp = function(a, b) { return b[by] - a[by]; };
- }
-
- // Reset link styles and format the selected sort option.
- $('a.sel').attr('href', '#').removeClass('sel');
- $('a.by' + by).removeAttr('href').addClass('sel');
- }
-
- /**
- * Create a comp function. If the user has preferences stored in
- * the sortBy cookie, use those, otherwise use the default.
- */
- function initComparator() {
- by = 'rating'; // Default to sort by rating.
- // If the sortBy cookie is set, use that instead.
- if (document.cookie.length > 0) {
- var start = document.cookie.indexOf('sortBy=');
- if (start != -1) {
- start = start + 7;
- var end = document.cookie.indexOf(";", start);
- if (end == -1) {
- end = document.cookie.length;
- by = unescape(document.cookie.substring(start, end));
- }
- }
- }
- setComparator();
- }
-
- /**
- * Show a comment div.
- */
- function show(id) {
- $('#ao' + id).hide();
- $('#ah' + id).show();
- var context = $.extend({id: id}, opts);
- var popup = $(renderTemplate(popupTemplate, context)).hide();
- popup.find('textarea[name="proposal"]').hide();
- popup.find('a.by' + by).addClass('sel');
- var form = popup.find('#cf' + id);
- form.submit(function(event) {
- event.preventDefault();
- addComment(form);
- });
- $('#s' + id).after(popup);
- popup.slideDown('fast', function() {
- getComments(id);
- });
- }
-
- /**
- * Hide a comment div.
- */
- function hide(id) {
- $('#ah' + id).hide();
- $('#ao' + id).show();
- var div = $('#sc' + id);
- div.slideUp('fast', function() {
- div.remove();
- });
- }
-
- /**
- * Perform an ajax request to get comments for a node
- * and insert the comments into the comments tree.
- */
- function getComments(id) {
- $.ajax({
- type: 'GET',
- url: opts.getCommentsURL,
- data: {node: id},
- success: function(data, textStatus, request) {
- var ul = $('#cl' + id);
- var speed = 100;
- $('#cf' + id)
- .find('textarea[name="proposal"]')
- .data('source', data.source);
-
- if (data.comments.length === 0) {
- ul.html('No comments yet.');
- ul.data('empty', true);
- } else {
- // If there are comments, sort them and put them in the list.
- var comments = sortComments(data.comments);
- speed = data.comments.length * 100;
- appendComments(comments, ul);
- ul.data('empty', false);
- }
- $('#cn' + id).slideUp(speed + 200);
- ul.slideDown(speed);
- },
- error: function(request, textStatus, error) {
- showError('Oops, there was a problem retrieving the comments.');
- },
- dataType: 'json'
- });
- }
-
- /**
- * Add a comment via ajax and insert the comment into the comment tree.
- */
- function addComment(form) {
- var node_id = form.find('input[name="node"]').val();
- var parent_id = form.find('input[name="parent"]').val();
- var text = form.find('textarea[name="comment"]').val();
- var proposal = form.find('textarea[name="proposal"]').val();
-
- if (text == '') {
- showError('Please enter a comment.');
- return;
- }
-
- // Disable the form that is being submitted.
- form.find('textarea,input').attr('disabled', 'disabled');
-
- // Send the comment to the server.
- $.ajax({
- type: "POST",
- url: opts.addCommentURL,
- dataType: 'json',
- data: {
- node: node_id,
- parent: parent_id,
- text: text,
- proposal: proposal
- },
- success: function(data, textStatus, error) {
- // Reset the form.
- if (node_id) {
- hideProposeChange(node_id);
- }
- form.find('textarea')
- .val('')
- .add(form.find('input'))
- .removeAttr('disabled');
- var ul = $('#cl' + (node_id || parent_id));
- if (ul.data('empty')) {
- $(ul).empty();
- ul.data('empty', false);
- }
- insertComment(data.comment);
- var ao = $('#ao' + node_id);
- ao.find('img').attr({'src': opts.commentBrightImage});
- if (node_id) {
- // if this was a "root" comment, remove the commenting box
- // (the user can get it back by reopening the comment popup)
- $('#ca' + node_id).slideUp();
- }
- },
- error: function(request, textStatus, error) {
- form.find('textarea,input').removeAttr('disabled');
- showError('Oops, there was a problem adding the comment.');
- }
- });
- }
-
- /**
- * Recursively append comments to the main comment list and children
- * lists, creating the comment tree.
- */
- function appendComments(comments, ul) {
- $.each(comments, function() {
- var div = createCommentDiv(this);
- ul.append($(document.createElement('li')).html(div));
- appendComments(this.children, div.find('ul.comment-children'));
- // To avoid stagnating data, don't store the comments children in data.
- this.children = null;
- div.data('comment', this);
- });
- }
-
- /**
- * After adding a new comment, it must be inserted in the correct
- * location in the comment tree.
- */
- function insertComment(comment) {
- var div = createCommentDiv(comment);
-
- // To avoid stagnating data, don't store the comments children in data.
- comment.children = null;
- div.data('comment', comment);
-
- var ul = $('#cl' + (comment.node || comment.parent));
- var siblings = getChildren(ul);
-
- var li = $(document.createElement('li'));
- li.hide();
-
- // Determine where in the parents children list to insert this comment.
- for(i=0; i < siblings.length; i++) {
- if (comp(comment, siblings[i]) <= 0) {
- $('#cd' + siblings[i].id)
- .parent()
- .before(li.html(div));
- li.slideDown('fast');
- return;
- }
- }
-
- // If we get here, this comment rates lower than all the others,
- // or it is the only comment in the list.
- ul.append(li.html(div));
- li.slideDown('fast');
- }
-
- function acceptComment(id) {
- $.ajax({
- type: 'POST',
- url: opts.acceptCommentURL,
- data: {id: id},
- success: function(data, textStatus, request) {
- $('#cm' + id).fadeOut('fast');
- $('#cd' + id).removeClass('moderate');
- },
- error: function(request, textStatus, error) {
- showError('Oops, there was a problem accepting the comment.');
- }
- });
- }
-
- function deleteComment(id) {
- $.ajax({
- type: 'POST',
- url: opts.deleteCommentURL,
- data: {id: id},
- success: function(data, textStatus, request) {
- var div = $('#cd' + id);
- if (data == 'delete') {
- // Moderator mode: remove the comment and all children immediately
- div.slideUp('fast', function() {
- div.remove();
- });
- return;
- }
- // User mode: only mark the comment as deleted
- div
- .find('span.user-id:first')
- .text('[deleted]').end()
- .find('div.comment-text:first')
- .text('[deleted]').end()
- .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
- ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
- .remove();
- var comment = div.data('comment');
- comment.username = '[deleted]';
- comment.text = '[deleted]';
- div.data('comment', comment);
- },
- error: function(request, textStatus, error) {
- showError('Oops, there was a problem deleting the comment.');
- }
- });
- }
-
- function showProposal(id) {
- $('#sp' + id).hide();
- $('#hp' + id).show();
- $('#pr' + id).slideDown('fast');
- }
-
- function hideProposal(id) {
- $('#hp' + id).hide();
- $('#sp' + id).show();
- $('#pr' + id).slideUp('fast');
- }
-
- function showProposeChange(id) {
- $('#pc' + id).hide();
- $('#hc' + id).show();
- var textarea = $('#pt' + id);
- textarea.val(textarea.data('source'));
- $.fn.autogrow.resize(textarea[0]);
- textarea.slideDown('fast');
- }
-
- function hideProposeChange(id) {
- $('#hc' + id).hide();
- $('#pc' + id).show();
- var textarea = $('#pt' + id);
- textarea.val('').removeAttr('disabled');
- textarea.slideUp('fast');
- }
-
- function toggleCommentMarkupBox(id) {
- $('#mb' + id).toggle();
- }
-
- /** Handle when the user clicks on a sort by link. */
- function handleReSort(link) {
- var classes = link.attr('class').split(/\s+/);
- for (var i=0; iThank you! Your comment will show up '
- + 'once it is has been approved by a moderator.');
- }
- // Prettify the comment rating.
- comment.pretty_rating = comment.rating + ' point' +
- (comment.rating == 1 ? '' : 's');
- // Make a class (for displaying not yet moderated comments differently)
- comment.css_class = comment.displayed ? '' : ' moderate';
- // Create a div for this comment.
- var context = $.extend({}, opts, comment);
- var div = $(renderTemplate(commentTemplate, context));
-
- // If the user has voted on this comment, highlight the correct arrow.
- if (comment.vote) {
- var direction = (comment.vote == 1) ? 'u' : 'd';
- div.find('#' + direction + 'v' + comment.id).hide();
- div.find('#' + direction + 'u' + comment.id).show();
- }
-
- if (opts.moderator || comment.text != '[deleted]') {
- div.find('a.reply').show();
- if (comment.proposal_diff)
- div.find('#sp' + comment.id).show();
- if (opts.moderator && !comment.displayed)
- div.find('#cm' + comment.id).show();
- if (opts.moderator || (opts.username == comment.username))
- div.find('#dc' + comment.id).show();
- }
- return div;
- }
-
- /**
- * A simple template renderer. Placeholders such as <%id%> are replaced
- * by context['id'] with items being escaped. Placeholders such as <#id#>
- * are not escaped.
- */
- function renderTemplate(template, context) {
- var esc = $(document.createElement('div'));
-
- function handle(ph, escape) {
- var cur = context;
- $.each(ph.split('.'), function() {
- cur = cur[this];
- });
- return escape ? esc.text(cur || "").html() : cur;
- }
-
- return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
- return handle(arguments[2], arguments[1] == '%' ? true : false);
- });
- }
-
- /** Flash an error message briefly. */
- function showError(message) {
- $(document.createElement('div')).attr({'class': 'popup-error'})
- .append($(document.createElement('div'))
- .attr({'class': 'error-message'}).text(message))
- .appendTo('body')
- .fadeIn("slow")
- .delay(2000)
- .fadeOut("slow");
- }
-
- /** Add a link the user uses to open the comments popup. */
- $.fn.comment = function() {
- return this.each(function() {
- var id = $(this).attr('id').substring(1);
- var count = COMMENT_METADATA[id];
- var title = count + ' comment' + (count == 1 ? '' : 's');
- var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
- var addcls = count == 0 ? ' nocomment' : '';
- $(this)
- .append(
- $(document.createElement('a')).attr({
- href: '#',
- 'class': 'sphinx-comment-open' + addcls,
- id: 'ao' + id
- })
- .append($(document.createElement('img')).attr({
- src: image,
- alt: 'comment',
- title: title
- }))
- .click(function(event) {
- event.preventDefault();
- show($(this).attr('id').substring(2));
- })
- )
- .append(
- $(document.createElement('a')).attr({
- href: '#',
- 'class': 'sphinx-comment-close hidden',
- id: 'ah' + id
- })
- .append($(document.createElement('img')).attr({
- src: opts.closeCommentImage,
- alt: 'close',
- title: 'close'
- }))
- .click(function(event) {
- event.preventDefault();
- hide($(this).attr('id').substring(2));
- })
- );
- });
- };
-
- var opts = {
- processVoteURL: '/_process_vote',
- addCommentURL: '/_add_comment',
- getCommentsURL: '/_get_comments',
- acceptCommentURL: '/_accept_comment',
- deleteCommentURL: '/_delete_comment',
- commentImage: '/static/_static/comment.png',
- closeCommentImage: '/static/_static/comment-close.png',
- loadingImage: '/static/_static/ajax-loader.gif',
- commentBrightImage: '/static/_static/comment-bright.png',
- upArrow: '/static/_static/up.png',
- downArrow: '/static/_static/down.png',
- upArrowPressed: '/static/_static/up-pressed.png',
- downArrowPressed: '/static/_static/down-pressed.png',
- voting: false,
- moderator: false
- };
-
- if (typeof COMMENT_OPTIONS != "undefined") {
- opts = jQuery.extend(opts, COMMENT_OPTIONS);
- }
-
- var popupTemplate = '\
- ';
-
- var commentTemplate = '\
- \
- ';
-
- var replyTemplate = '\
- \
- \
- \
-
\
- ';
-
- $(document).ready(function() {
- init();
- });
-})(jQuery);
-
-$(document).ready(function() {
- // add comment anchors for all paragraphs that are commentable
- $('.sphinx-has-comment').comment();
-
- // highlight search words in search results
- $("div.context").each(function() {
- var params = $.getQueryParameters();
- var terms = (params.q) ? params.q[0].split(/\s+/) : [];
- var result = $(this);
- $.each(terms, function() {
- result.highlightText(this.toLowerCase(), 'highlighted');
- });
- });
-
- // directly open comment window if requested
- var anchor = document.location.hash;
- if (anchor.substring(0, 9) == '#comment-') {
- $('#ao' + anchor.substring(9)).click();
- document.location.hash = '#s' + anchor.substring(9);
- }
-});
diff --git a/docs/build/html/classes.html b/docs/build/html/classes.html
deleted file mode 100644
index 7fb7ec335..000000000
--- a/docs/build/html/classes.html
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Netmiko Classes — Netmiko 1.0 documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/build/html/classes/base_connection.html b/docs/build/html/classes/base_connection.html
deleted file mode 100644
index 4f2ff9a05..000000000
--- a/docs/build/html/classes/base_connection.html
+++ /dev/null
@@ -1,541 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- BaseConnection — Netmiko 1.0 documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
BaseConnection
-
--
-class
netmiko.base_connection.BaseConnection(ip=u'', host=u'', username=u'', password=u'', secret=u'', port=None, device_type=u'', verbose=False, global_delay_factor=1, use_keys=False, key_file=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file=u'', ssh_config_file=None, timeout=8)
-Defines vendor independent methods.
-Otherwise method left as a stub method.
-
--
-
__enter__()
-Enter runtime context
-
-
-
--
-
__exit__(exc_type, exc_value, traceback)
-Gracefully close connection on context manager exit
-
-
-
--
-
__init__(ip=u'', host=u'', username=u'', password=u'', secret=u'', port=None, device_type=u'', verbose=False, global_delay_factor=1, use_keys=False, key_file=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file=u'', ssh_config_file=None, timeout=8)
-Initialize attributes for establishing connection to target device.
-
-
-
-
-| Parameters: |
-- ip (str) – IP address of target device. Not required if host is
-provided.
-- host (str) – Hostname of target device. Not required if ip is
-provided.
-- username (str) – Username to authenticate against target device if
-required.
-- password (str) – Password to authenticate against target device if
-required.
-- secret (str) – The enable password if target device requires one.
-- port (int or None) – The destination port used to connect to the target
-device.
-- device_type (str) – Class selection based on device type.
-- verbose (bool) – If True enables more verbose logging.
-- global_delay_factor (int) – Controls global delay factor value.
-- use_keys (bool) – If true, Paramiko will attempt to connect to
-target device using SSH keys.
-- key_file (str) – Name of the SSH key file to use for Paramiko
-SSH connection authentication.
-- allow_agent (bool) – Set to True to enable connect to the SSH agent
-- ssh_strict (bool) – If True Paramiko will automatically reject
-unknown hostname and keys. If ‘False’ Paramiko will
-automatically add the hostname and new host key.
-- system_host_keys (bool) – If True Paramiko will load host keys
-from the user’s local ‘known hosts’ file.
-- alt_host_keys (bool) – If True host keys will be loaded from
-a local host-key file.
-- alt_key_file (str) – If alt_host_keys is set to True, provide
-the filename of the local host-key file to load.
-- ssh_config_file (str) – File name of a OpenSSH configuration file
-to load SSH connection parameters from.
-- timeout (float) – Set a timeout on blocking read/write operations.
-
- |
-
-
-
-
-
-
--
-
__weakref__
-list of weak references to the object (if defined)
-
-
-
--
-
check_config_mode(check_string=u'', pattern=u'')
-Checks if the device is in configuration mode or not.
-
-
-
--
-
check_enable_mode(check_string=u'')
-Check if in enable mode. Return boolean.
-
-
-
--
-
cleanup()
-Any needed cleanup before closing connection.
-
-
-
--
-
clear_buffer()
-Read any data available in the channel.
-
-
-
--
-
commit()
-Commit method for platforms that support this.
-
-
-
--
-
config_mode(config_command=u'', pattern=u'')
-Enter into config_mode.
-
-
-
--
-
disable_paging(command=u'terminal length 0', delay_factor=1)
-Disable paging default to a Cisco CLI method.
-
-
-
--
-
disconnect()
-Gracefully close the SSH connection.
-
-
-
--
-
enable(cmd=u'', pattern=u'password', re_flags=2)
-Enter enable mode.
-
-
-
--
-
establish_connection(width=None, height=None)
-Establish SSH connection to the network device
-Timeout will generate a NetMikoTimeoutException
-Authentication failure will generate a NetMikoAuthenticationException
-width and height are needed for Fortinet paging setting.
-
-
-
--
-
exit_config_mode(exit_config=u'', pattern=u'')
-Exit from configuration mode.
-
-
-
--
-
exit_enable_mode(exit_command=u'')
-Exit enable mode.
-
-
-
--
-
find_prompt(delay_factor=1)
-Finds the current network device prompt, last line only.
-
-
-
--
-static
normalize_cmd(command)
-Normalize CLI commands to have a single trailing newline.
-
-
-
--
-static
normalize_linefeeds(a_string)
-Convert ‘
-‘,’
-‘, ‘
-‘ to ‘
-.
-
-
-
--
-
read_channel()
-Generic handler that will read all the data from an SSH or telnet channel.
-
-
-
--
-
read_until_pattern(*args, **kwargs)
-Read channel until pattern detected. Return ALL data available.
-
-
-
--
-
read_until_prompt(*args, **kwargs)
-Read channel until self.base_prompt detected. Return ALL data available.
-
-
-
--
-
read_until_prompt_or_pattern(pattern=u'', re_flags=0)
-Read until either self.base_prompt or pattern is detected. Return ALL data available.
-
-
-
--
-
select_delay_factor(delay_factor)
-Choose the greater of delay_factor or self.global_delay_factor.
-
-
-
--
-
send_command(command_string, expect_string=None, delay_factor=1, max_loops=500, auto_find_prompt=True, strip_prompt=True, strip_command=True)
-Send command to network device retrieve output until router_prompt or expect_string
-By default this method will keep waiting to receive data until the network device prompt is
-detected. The current network device prompt will be determined automatically.
-command_string = command to execute
-expect_string = pattern to search for uses re.search (use raw strings)
-delay_factor = decrease the initial delay before we start looking for data
-max_loops = number of iterations before we give up and raise an exception
-strip_prompt = strip the trailing prompt from the output
-strip_command = strip the leading command from the output
-
-
-
--
-
send_command_expect(*args, **kwargs)
-Support previous name of send_command method.
-
-
-
--
-
send_command_timing(command_string, delay_factor=1, max_loops=150, strip_prompt=True, strip_command=True)
-Execute command_string on the SSH channel.
-Use delay based mechanism to obtain output. Strips echoed characters and router prompt.
-delay_factor can be used to increase the delays.
-max_loops can be used to increase the number of times it reads the data buffer
-Returns the output of the command.
-
-
-
--
-
send_config_from_file(config_file=None, **kwargs)
-Send configuration commands down the SSH channel from a file.
-The file is processed line-by-line and each command is sent down the
-SSH channel.
-**kwargs are passed to send_config_set method.
-
-
-
--
-
send_config_set(config_commands=None, exit_config_mode=True, delay_factor=1, max_loops=150, strip_prompt=False, strip_command=False)
-Send configuration commands down the SSH channel.
-config_commands is an iterable containing all of the configuration commands.
-The commands will be executed one after the other.
-Automatically exits/enters configuration mode.
-
-
-
--
-
session_preparation()
-Prepare the session after the connection has been established
-This method handles some of vagaries that occur between various devices
-early on in the session.
-In general, it should include:
-self.set_base_prompt()
-self.disable_paging()
-self.set_terminal_width()
-
-
-
--
-
set_base_prompt(pri_prompt_terminator=u'#', alt_prompt_terminator=u'>', delay_factor=1)
-Sets self.base_prompt
-Used as delimiter for stripping of trailing prompt in output.
-Should be set to something that is general and applies in multiple contexts. For Cisco
-devices this will be set to router hostname (i.e. prompt without ‘>’ or ‘#’).
-This will be set on entering user exec or privileged exec on Cisco, but not when
-entering/exiting config mode.
-
-
-
--
-
set_terminal_width(command=u'', 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.
-
-
-
--
-
special_login_handler(delay_factor=1)
-Handler for devices like WLC, Avaya ERS that throw up characters prior to login.
-
-
-
--
-static
strip_ansi_escape_codes(string_buffer)
-Remove any ANSI (VT100) ESC codes from the output
-http://en.wikipedia.org/wiki/ANSI_escape_code
-Note: this does not capture ALL possible ANSI Escape Codes only the ones
-I have encountered
-Current codes that are filtered:
-ESC = ‘’ or chr(27)
-ESC = is the escape character [^ in hex (‘’)
-ESC[24;27H Position cursor
-ESC[?25h Show the cursor
-ESC[E Next line (HP does ESC-E)
-ESC[2K Erase line
-ESC[1;24r Enable scrolling from start to row end
-HP ProCurve’s, Cisco SG300, and F5 LTM’s require this (possible others)
-
-
-
--
-static
strip_backspaces(output)
-Strip any backspace characters out of the output.
-
-
-
--
-static
strip_command(command_string, output)
-Strip command_string from output string
-Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
-
-
-
--
-
strip_prompt(a_string)
-Strip the trailing router prompt from the output.
-
-
-
--
-
telnet_login(pri_prompt_terminator=u'#', alt_prompt_terminator=u'>', delay_factor=1, max_loops=60)
-Telnet login. Can be username/password or just password.
-
-
-
--
-
write_channel(out_data)
-Generic handler that will write to both SSH and telnet channel.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html
deleted file mode 100644
index 4f96a07cf..000000000
--- a/docs/build/html/genindex.html
+++ /dev/null
@@ -1,447 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Index — Netmiko 1.0 documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index
-
-
-
_
- |
B
- |
C
- |
D
- |
E
- |
F
- |
N
- |
R
- |
S
- |
T
- |
W
-
-
-
_
-
-
-
B
-
-
-
C
-
-
-
D
-
-
-
E
-
-
-
F
-
-
-
N
-
-
-
R
-
-
-
S
-
-
-
T
-
-
-
W
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/build/html/index.html b/docs/build/html/index.html
deleted file mode 100644
index 5ea9f71a0..000000000
--- a/docs/build/html/index.html
+++ /dev/null
@@ -1,219 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Welcome to Netmiko’s documentation! — Netmiko 1.0 documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Welcome to Netmiko’s documentation!
-
Contents:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv
deleted file mode 100644
index d8e04fa1c..000000000
Binary files a/docs/build/html/objects.inv and /dev/null differ
diff --git a/docs/build/html/search.html b/docs/build/html/search.html
deleted file mode 100644
index d71ad7c6c..000000000
--- a/docs/build/html/search.html
+++ /dev/null
@@ -1,207 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Search — Netmiko 1.0 documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js
deleted file mode 100644
index 60b7ca519..000000000
--- a/docs/build/html/searchindex.js
+++ /dev/null
@@ -1 +0,0 @@
-Search.setIndex({envversion:49,filenames:["classes","classes/base_connection","index"],objects:{"netmiko.base_connection":{BaseConnection:[1,0,1,""]},"netmiko.base_connection.BaseConnection":{__enter__:[1,1,1,""],__exit__:[1,1,1,""],__init__:[1,1,1,""],__weakref__:[1,2,1,""],check_config_mode:[1,1,1,""],check_enable_mode:[1,1,1,""],cleanup:[1,1,1,""],clear_buffer:[1,1,1,""],commit:[1,1,1,""],config_mode:[1,1,1,""],disable_paging:[1,1,1,""],disconnect:[1,1,1,""],enable:[1,1,1,""],establish_connection:[1,1,1,""],exit_config_mode:[1,1,1,""],exit_enable_mode:[1,1,1,""],find_prompt:[1,1,1,""],normalize_cmd:[1,3,1,""],normalize_linefeeds:[1,3,1,""],read_channel:[1,1,1,""],read_until_pattern:[1,1,1,""],read_until_prompt:[1,1,1,""],read_until_prompt_or_pattern:[1,1,1,""],select_delay_factor:[1,1,1,""],send_command:[1,1,1,""],send_command_expect:[1,1,1,""],send_command_timing:[1,1,1,""],send_config_from_file:[1,1,1,""],send_config_set:[1,1,1,""],session_preparation:[1,1,1,""],set_base_prompt:[1,1,1,""],set_terminal_width:[1,1,1,""],special_login_handler:[1,1,1,""],strip_ansi_escape_codes:[1,3,1,""],strip_backspaces:[1,3,1,""],strip_command:[1,3,1,""],strip_prompt:[1,1,1,""],telnet_login:[1,1,1,""],write_channel:[1,1,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","staticmethod","Python static method"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute","3":"py:staticmethod"},terms:{"24r":1,"25h":1,"27h":1,"boolean":1,"default":1,"float":1,"int":1,"long":1,"new":1,"return":1,"static":1,"throw":1,"true":1,"try":1,__enter__:1,__exit__:1,__init__:1,__weakref__:1,a_str:1,access:1,add:1,address:1,adjust:1,after:1,against:1,agent:1,all:1,allow_ag:1,alt_host_kei:1,alt_key_fil:1,alt_prompt_termin:1,ani:1,ansi:1,ansi_escape_cod:1,any:1,appli:1,arg:1,attempt:1,attribut:1,authent:1,auto_find_prompt:1,automat:1,avail:1,avaya:1,backspac:1,base:1,base_connect:1,base_prompt:1,baseconnect:0,been:1,befor:1,between:1,block:1,bool:1,both:1,broad:1,buffer:1,can:1,captur:1,caus:1,channel:1,charact:1,check:1,check_config_mod:1,check_enable_mod:1,check_str:1,choos:1,chr:1,cisco:1,cleanup:1,clear_buff:1,cli:1,close:1,cmd:1,code:1,command:1,command_str:1,commit:1,config:1,config_command:1,config_fil:1,config_mod:1,configur:1,connect:1,contain:1,content:2,context:1,control:1,convert:1,current:1,cursor:1,data:1,decreas:1,defin:1,delai:1,delay_factor:1,delimit:1,destin:1,detect:1,determin:1,devic:1,device_typ:1,disabl:1,disable_pag:1,disconnect:1,distort:1,doe:1,down:1,each:1,earli:1,echo:1,either:1,enabl:1,encount:1,end:1,enter:1,erase:1,ers:1,esc:1,escap:1,escape:1,establish:1,establish_connect:1,exc_typ:1,exc_valu:1,except:1,exec:1,execut:1,exit:1,exit_command:1,exit_config:1,exit_config_mod:1,exit_enable_mod:1,expect_str:1,factor:1,failur:1,fals:1,file:1,filenam:1,filter:1,find:1,find_prompt:1,fortinet:1,from:1,gener:1,get:1,give:1,global:1,global_delay_factor:1,gracefulli:1,greater:1,handl:1,handler:1,have:1,height:1,hex:1,host:1,hostnam:1,http:1,includ:1,increas:1,independ:1,index:2,initi:1,initial:1,ios:1,iter:1,just:1,keep:1,kei:1,key_fil:1,known:1,kwarg:1,last:1,lead:1,left:1,length:1,like:1,line:1,list:1,load:1,local:1,log:1,login:1,look:1,ltm:1,manag:1,max_loop:1,mechan:1,method:1,mode:1,modul:2,more:1,multipl:1,name:1,need:1,netmikoauthenticationexcept:1,netmikotimeoutexcept:1,network:1,newlin:1,next:1,none:1,normal:1,normalize_cmd:1,normalize_linefe:1,note:1,number:1,object:1,obtain:1,occur:1,onli:1,openssh:1,oper:1,org:1,other:1,otherwis:1,out:1,out_data:1,output:1,page:[1,2],paramet:1,paramiko:1,pass:1,password:1,pattern:1,platform:1,port:1,posit:1,possibl:1,prepar:1,previou:1,pri_prompt_termin:1,prior:1,privileg:1,process:1,procurv:1,programmat:1,prompt:1,provid:1,rais:1,raw:1,re_flag:1,read:1,read_channel:1,read_until_pattern:1,read_until_prompt:1,read_until_prompt_or_pattern:1,receiv:1,refer:1,reject:1,remov:1,requir:1,retriev:1,router:1,router_prompt:1,row:1,runtim:1,scroll:1,search:[1,2],secret:1,select:1,select_delay_factor:1,self:1,send:1,send_command:1,send_command_expect:1,send_command_tim:1,send_config_from_fil:1,send_config_set:1,sent:1,session:1,session_prepar:1,set:1,set_base_prompt:1,set_terminal_width:1,sg300:1,should:1,show:1,singl:1,some:1,someth:1,special_login_handl:1,ssh:1,ssh_config_fil:1,ssh_strict:1,start:1,str:1,string:1,string_buff:1,strip:1,strip_ansi_escape_cod:1,strip_backspac:1,strip_command:1,strip_prompt:1,stub:1,support:1,system_host_kei:1,target:1,telnet:1,telnet_login:1,termin:1,thi:1,time:1,timeout:1,traceback:1,trail:1,type:1,unknown:1,until:1,use:1,use_kei:1,used:1,user:1,usernam:1,vagari:1,valu:1,variou:1,vendor:1,verbos:1,vt100:1,wait:1,weak:1,when:1,which:1,width:1,wiki:1,wikipedia:1,without:1,wlc:1,work:1,wrap:1,write:1,write_channel:1},titles:["Netmiko Classes","BaseConnection","Welcome to Netmiko’s documentation!"],titleterms:{"class":0,baseconnect:1,document:2,indice:2,netmiko:[0,2],tabl:2,welcom:2}})
\ No newline at end of file
diff --git a/docs/doc-requirements.txt b/docs/doc-requirements.txt
deleted file mode 100644
index cbf1e3658..000000000
--- a/docs/doc-requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-sphinx
-sphinx-rtd-theme
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 000000000..9f2435dad
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,8 @@
+Netmiko Documentation has Moved!
+================================
+
+.. contents::
+
+Netmiko documentation has moved to GitHub Pages!
+
+You can find the README for Netmiko `here `__, and the API documentation `here `__.
diff --git a/docs/make.bat b/docs/make.bat
deleted file mode 100644
index 2af7431c6..000000000
--- a/docs/make.bat
+++ /dev/null
@@ -1,281 +0,0 @@
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
-set I18NSPHINXOPTS=%SPHINXOPTS% source
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^` where ^ is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. epub3 to make an epub3
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. xml to make Docutils-native XML files
- echo. pseudoxml to make pseudoxml-XML files for display purposes
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- echo. coverage to run coverage check of the documentation if enabled
- echo. dummy to check syntax errors of document sources
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-REM Check if sphinx-build is available and fallback to Python version if any
-%SPHINXBUILD% 1>NUL 2>NUL
-if errorlevel 9009 goto sphinx_python
-goto sphinx_ok
-
-:sphinx_python
-
-set SPHINXBUILD=python -m sphinx.__init__
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-:sphinx_ok
-
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Netmiko.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Netmiko.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "epub3" (
- %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdf" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf
- cd %~dp0
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdfja" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf-ja
- cd %~dp0
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-if "%1" == "coverage" (
- %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of coverage in the sources finished, look at the ^
-results in %BUILDDIR%/coverage/python.txt.
- goto end
-)
-
-if "%1" == "xml" (
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
- goto end
-)
-
-if "%1" == "pseudoxml" (
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
- goto end
-)
-
-if "%1" == "dummy" (
- %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. Dummy builder generates no files.
- goto end
-)
-
-:end
diff --git a/docs/netmiko/a10/a10_ssh.html b/docs/netmiko/a10/a10_ssh.html
new file mode 100644
index 000000000..394134f04
--- /dev/null
+++ b/docs/netmiko/a10/a10_ssh.html
@@ -0,0 +1,311 @@
+
+
+
+
+
+
+netmiko.a10.a10_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.a10.a10_ssh
+
+
+A10 support.
+
+Source code
+"""A10 support."""
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class A10SSH(CiscoSSHConnection):
+ """A10 support."""
+
+ def session_preparation(self) -> None:
+ """A10 requires to be enable mode to disable paging."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class A10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
A10 support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class A10SSH(CiscoSSHConnection):
+ """A10 support."""
+
+ def session_preparation(self) -> None:
+ """A10 requires to be enable mode to disable paging."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
A10 requires to be enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """A10 requires to be enable mode to disable paging."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/a10/index.html b/docs/netmiko/a10/index.html
new file mode 100644
index 000000000..e9903e2f0
--- /dev/null
+++ b/docs/netmiko/a10/index.html
@@ -0,0 +1,303 @@
+
+
+
+
+
+
+netmiko.a10 API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.a10.a10_ssh import A10SSH
+
+__all__ = ["A10SSH"]
+
+
+
+
+
+
+
+
+
+class A10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
A10 support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class A10SSH(CiscoSSHConnection):
+ """A10 support."""
+
+ def session_preparation(self) -> None:
+ """A10 requires to be enable mode to disable paging."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
A10 requires to be enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """A10 requires to be enable mode to disable paging."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/accedian/accedian_ssh.html b/docs/netmiko/accedian/accedian_ssh.html
new file mode 100644
index 000000000..23062de0e
--- /dev/null
+++ b/docs/netmiko/accedian/accedian_ssh.html
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+netmiko.accedian.accedian_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.accedian.accedian_ssh
+
+
+
+Source code
+from typing import Optional
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class AccedianSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[:#]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class AccedianSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AccedianSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[:#]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='#', delay_factor=2.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/accedian/index.html b/docs/netmiko/accedian/index.html
new file mode 100644
index 000000000..a626e5195
--- /dev/null
+++ b/docs/netmiko/accedian/index.html
@@ -0,0 +1,326 @@
+
+
+
+
+
+
+netmiko.accedian API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.accedian
+
+
+
+Source code
+from netmiko.accedian.accedian_ssh import AccedianSSH
+
+__all__ = ["AccedianSSH"]
+
+
+
+
+
+
+
+
+
+class AccedianSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AccedianSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[:#]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='#', delay_factor=2.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/adtran/adtran.html b/docs/netmiko/adtran/adtran.html
new file mode 100644
index 000000000..f9ab8d592
--- /dev/null
+++ b/docs/netmiko/adtran/adtran.html
@@ -0,0 +1,750 @@
+
+
+
+
+
+
+netmiko.adtran.adtran API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.adtran.adtran
+
+
+
+Source code
+from typing import Any, Optional
+import re
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class AdtranOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config term", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+class AdtranOSSSH(AdtranOSBase):
+ pass
+
+
+class AdtranOSTelnet(AdtranOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class AdtranOSBase
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AdtranOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config term", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def config_mode(self, config_command='config term', pattern='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "config term", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+
+
+Inherited members
+
+
+
+class AdtranOSSSH
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AdtranOSSSH(AdtranOSBase):
+ pass
+
+Ancestors
+
+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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AdtranOSTelnet(AdtranOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/adtran/index.html b/docs/netmiko/adtran/index.html
new file mode 100644
index 000000000..0386aecd4
--- /dev/null
+++ b/docs/netmiko/adtran/index.html
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+netmiko.adtran API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.adtran.adtran import AdtranOSSSH, AdtranOSTelnet
+
+__all__ = ["AdtranOSSSH", "AdtranOSTelnet"]
+
+
+
+
+
+
+
+
+
+class AdtranOSSSH
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AdtranOSSSH(AdtranOSBase):
+ pass
+
+Ancestors
+
+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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AdtranOSTelnet(AdtranOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/alcatel/alcatel_aos_ssh.html b/docs/netmiko/alcatel/alcatel_aos_ssh.html
new file mode 100644
index 000000000..81aa5abd2
--- /dev/null
+++ b/docs/netmiko/alcatel/alcatel_aos_ssh.html
@@ -0,0 +1,302 @@
+
+
+
+
+
+
+netmiko.alcatel.alcatel_aos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.alcatel.alcatel_aos_ssh
+
+
+Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8).
+
+Source code
+"""Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class AlcatelAosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
+
+ def session_preparation(self) -> None:
+ # Prompt can be anything, but best practice is to end with > or #
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class AlcatelAosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AlcatelAosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
+
+ def session_preparation(self) -> None:
+ # Prompt can be anything, but best practice is to end with > or #
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='write memory flash-synchro', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/alcatel/alcatel_sros_ssh.html b/docs/netmiko/alcatel/alcatel_sros_ssh.html
new file mode 100644
index 000000000..fbfa3328a
--- /dev/null
+++ b/docs/netmiko/alcatel/alcatel_sros_ssh.html
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+netmiko.alcatel.alcatel_sros_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.alcatel.alcatel_sros_ssh
+
+
+Alcatel-Lucent SROS support.
+
+Source code
+"""Alcatel-Lucent SROS support."""
+from __future__ import print_function
+from __future__ import unicode_literals
+import re
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class AlcatelSrosSSH(CiscoSSHConnection):
+ """Alcatel-Lucent SROS support."""
+
+ def session_preparation(self):
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="environment no more")
+ # 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(AlcatelSrosSSH, self).set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)(>.*)*#", cur_base_prompt)
+ if match:
+ # strip off >... from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+
+ def enable(self, cmd="enable-admin", pattern="ssword", re_flags=re.IGNORECASE):
+ """Enter enable mode."""
+ return super(AlcatelSrosSSH, self).enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_enable_mode(self, check_string="CLI Already in admin mode"):
+ """Check whether we are in enable-admin mode.
+ SROS requires us to do this:
+ *A:HOSTNAME# enable-admin
+ MINOR: CLI Already in admin mode.
+ *A:HOSTNAME#
+ *A:HOSTNAME# enable-admin
+ Password:
+ MINOR: CLI Invalid password.
+ *A:HOSTNAME#
+ """
+ output = self.send_command_timing("enable-admin")
+ if re.search(r"ssword", output):
+ # Just hit enter as we don't actually want to enter enable here
+ self.write_channel(self.normalize_cmd(self.RETURN))
+ self.read_until_prompt()
+ return False
+ elif check_string in output:
+ return True
+ raise ValueError("Unexpected response in check_enable_mode() method")
+
+ def exit_enable_mode(self, exit_command=""):
+ """No corresponding exit of enable mode on SROS."""
+ pass
+
+ def config_mode(self, config_command="configure", pattern="#"):
+ """ Enter into configuration mode on SROS device."""
+ return super(AlcatelSrosSSH, self).config_mode(
+ config_command=config_command, pattern=pattern
+ )
+
+ def exit_config_mode(self, exit_config="exit all", pattern="#"):
+ """ Exit from configuration mode."""
+ return super(AlcatelSrosSSH, self).exit_config_mode(
+ exit_config=exit_config, pattern=pattern
+ )
+
+ def check_config_mode(self, check_string="config", pattern="#"):
+ """ Checks if the device is in configuration mode or not. """
+ return super(AlcatelSrosSSH, self).check_config_mode(
+ check_string=check_string, pattern=pattern
+ )
+
+ def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class AlcatelSrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, 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, timeout=100, session_timeout=60, auth_timeout=None, blocking_timeout=8, banner_timeout=5, 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')
+
+-
+
Alcatel-Lucent SROS 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
+
+
+Source code
+class AlcatelSrosSSH(CiscoSSHConnection):
+ """Alcatel-Lucent SROS support."""
+
+ def session_preparation(self):
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="environment no more")
+ # 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(AlcatelSrosSSH, self).set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)(>.*)*#", cur_base_prompt)
+ if match:
+ # strip off >... from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+
+ def enable(self, cmd="enable-admin", pattern="ssword", re_flags=re.IGNORECASE):
+ """Enter enable mode."""
+ return super(AlcatelSrosSSH, self).enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_enable_mode(self, check_string="CLI Already in admin mode"):
+ """Check whether we are in enable-admin mode.
+ SROS requires us to do this:
+ *A:HOSTNAME# enable-admin
+ MINOR: CLI Already in admin mode.
+ *A:HOSTNAME#
+ *A:HOSTNAME# enable-admin
+ Password:
+ MINOR: CLI Invalid password.
+ *A:HOSTNAME#
+ """
+ output = self.send_command_timing("enable-admin")
+ if re.search(r"ssword", output):
+ # Just hit enter as we don't actually want to enter enable here
+ self.write_channel(self.normalize_cmd(self.RETURN))
+ self.read_until_prompt()
+ return False
+ elif check_string in output:
+ return True
+ raise ValueError("Unexpected response in check_enable_mode() method")
+
+ def exit_enable_mode(self, exit_command=""):
+ """No corresponding exit of enable mode on SROS."""
+ pass
+
+ def config_mode(self, config_command="configure", pattern="#"):
+ """ Enter into configuration mode on SROS device."""
+ return super(AlcatelSrosSSH, self).config_mode(
+ config_command=config_command, pattern=pattern
+ )
+
+ def exit_config_mode(self, exit_config="exit all", pattern="#"):
+ """ Exit from configuration mode."""
+ return super(AlcatelSrosSSH, self).exit_config_mode(
+ exit_config=exit_config, pattern=pattern
+ )
+
+ def check_config_mode(self, check_string="config", pattern="#"):
+ """ Checks if the device is in configuration mode or not. """
+ return super(AlcatelSrosSSH, self).check_config_mode(
+ check_string=check_string, pattern=pattern
+ )
+
+ def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='config', pattern='#')
+
+-
+
Checks if the device is in configuration mode or not.
+
+Source code
+def check_config_mode(self, check_string="config", pattern="#"):
+ """ Checks if the device is in configuration mode or not. """
+ return super(AlcatelSrosSSH, self).check_config_mode(
+ check_string=check_string, pattern=pattern
+ )
+
+
+
+def check_enable_mode(self, check_string='CLI Already in admin mode')
+
+-
+
Check whether we are in enable-admin mode.
+SROS requires us to do this:
+A:HOSTNAME# enable-admin
+MINOR: CLI Already in admin mode.
+A:HOSTNAME#
+A:HOSTNAME# enable-admin
+Password:
+MINOR: CLI Invalid password.
+A:HOSTNAME#
+
+Source code
+def check_enable_mode(self, check_string="CLI Already in admin mode"):
+ """Check whether we are in enable-admin mode.
+ SROS requires us to do this:
+ *A:HOSTNAME# enable-admin
+ MINOR: CLI Already in admin mode.
+ *A:HOSTNAME#
+ *A:HOSTNAME# enable-admin
+ Password:
+ MINOR: CLI Invalid password.
+ *A:HOSTNAME#
+ """
+ output = self.send_command_timing("enable-admin")
+ if re.search(r"ssword", output):
+ # Just hit enter as we don't actually want to enter enable here
+ self.write_channel(self.normalize_cmd(self.RETURN))
+ self.read_until_prompt()
+ return False
+ elif check_string in output:
+ return True
+ raise ValueError("Unexpected response in check_enable_mode() method")
+
+
+
+def config_mode(self, config_command='configure', pattern='#')
+
+-
+
Enter into configuration mode on SROS device.
+
+Source code
+def config_mode(self, config_command="configure", pattern="#"):
+ """ Enter into configuration mode on SROS device."""
+ return super(AlcatelSrosSSH, self).config_mode(
+ config_command=config_command, pattern=pattern
+ )
+
+
+
+def exit_enable_mode(self, exit_command='')
+
+-
+
No corresponding exit of enable mode on SROS.
+
+Source code
+def exit_enable_mode(self, exit_command=""):
+ """No corresponding exit of enable mode on SROS."""
+ pass
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+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(AlcatelSrosSSH, self).set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)(>.*)*#", cur_base_prompt)
+ if match:
+ # strip off >... from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/alcatel/index.html b/docs/netmiko/alcatel/index.html
new file mode 100644
index 000000000..c650d1984
--- /dev/null
+++ b/docs/netmiko/alcatel/index.html
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+netmiko.alcatel API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.alcatel
+
+
+
+Source code
+from netmiko.alcatel.alcatel_aos_ssh import AlcatelAosSSH
+
+__all__ = ["AlcatelAosSSH"]
+
+
+
+
+
+
+
+
+
+class AlcatelAosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AlcatelAosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
+
+ def session_preparation(self) -> None:
+ # Prompt can be anything, but best practice is to end with > or #
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='write memory flash-synchro', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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..c0aa2a9a9
--- /dev/null
+++ b/docs/netmiko/allied_telesis/allied_telesis_awplus.html
@@ -0,0 +1,543 @@
+
+
+
+
+
+
+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) -> None:
+ """
+ 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) -> str:
+ """Enter the Bourne Shell."""
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
+
+ def _return_cli(self) -> str:
+ """Return to the Awplus CLI."""
+ return self._send_command_str("exit", expect_string=r"[#>]")
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "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
+
+
+
+
+
+
+
+
+
+class AlliedTelesisAwplusBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AlliedTelesisAwplusBase(CiscoBaseConnection):
+ """Implement methods for interacting with Allied Telesis devices."""
+
+ def session_preparation(self) -> None:
+ """
+ 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) -> str:
+ """Enter the Bourne Shell."""
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
+
+ def _return_cli(self) -> str:
+ """Return to the Awplus CLI."""
+ return self._send_command_str("exit", expect_string=r"[#>]")
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "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='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "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) -> None:
+ """
+ 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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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..b2985295a
--- /dev/null
+++ b/docs/netmiko/allied_telesis/index.html
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+netmiko.allied_telesis API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.allied_telesis
+
+
+
+Source code
+from netmiko.allied_telesis.allied_telesis_awplus import AlliedTelesisAwplusSSH
+
+__all__ = ["AlliedTelesisAwplusSSH"]
+
+
+
+
+
+
+
+
+
+class AlliedTelesisAwplusSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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
new file mode 100644
index 000000000..6f5b09867
--- /dev/null
+++ b/docs/netmiko/apresia/apresia_aeos.html
@@ -0,0 +1,679 @@
+
+
+
+
+
+
+netmiko.apresia.apresia_aeos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.apresia.apresia_aeos
+
+
+
+Source code
+from typing import Any, Optional
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ApresiaAeosBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+
+ self.enable()
+ check_command = f"show running-config | include {command}"
+ show_run = self._send_command_str(check_command)
+
+ output = ""
+ if self.allow_auto_change and command not in show_run:
+ output += super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+ self.exit_enable_mode()
+ return output
+
+
+class ApresiaAeosSSH(ApresiaAeosBase):
+ pass
+
+
+class ApresiaAeosTelnet(ApresiaAeosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class ApresiaAeosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ApresiaAeosBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+
+ self.enable()
+ check_command = f"show running-config | include {command}"
+ show_run = self._send_command_str(check_command)
+
+ output = ""
+ if self.allow_auto_change and command not in show_run:
+ output += super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+ self.exit_enable_mode()
+ return output
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+
+
+Inherited members
+
+
+
+class ApresiaAeosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ApresiaAeosSSH(ApresiaAeosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ApresiaAeosTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ApresiaAeosTelnet(ApresiaAeosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/apresia/index.html b/docs/netmiko/apresia/index.html
new file mode 100644
index 000000000..432058152
--- /dev/null
+++ b/docs/netmiko/apresia/index.html
@@ -0,0 +1,427 @@
+
+
+
+
+
+
+netmiko.apresia API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.apresia
+
+
+
+Source code
+from netmiko.apresia.apresia_aeos import ApresiaAeosSSH, ApresiaAeosTelnet
+
+__all__ = ["ApresiaAeosSSH", "ApresiaAeosTelnet"]
+
+
+
+
+
+
+
+
+
+class ApresiaAeosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ApresiaAeosSSH(ApresiaAeosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ApresiaAeosTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ApresiaAeosTelnet(ApresiaAeosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/arista/arista.html b/docs/netmiko/arista/arista.html
new file mode 100644
index 000000000..7792ecae4
--- /dev/null
+++ b/docs/netmiko/arista/arista.html
@@ -0,0 +1,968 @@
+
+
+
+
+
+
+netmiko.arista.arista API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.arista.arista
+
+
+
+Source code
+from typing import Any, Optional, Union, Sequence
+from typing import TYPE_CHECKING
+import re
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.cisco_base_connection import CiscoFileTransfer
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
+
+class AristaBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ # Arista will echo immediately and then when the device really responds (like NX-OS)
+ self.set_terminal_width(command=cmd, pattern=r"Width set to")
+ self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled")
+ self.set_base_prompt()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Arista, unfortunately, does this:
+ loc1-core01(s1)#
+
+ Can also be (s2)
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ output = output.replace("(s1)", "")
+ output = output.replace("(s2)", "")
+ return check_string in output
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Force arista to read pattern all the way to prompt on the next line."""
+
+ if not re_flags:
+ re_flags = re.DOTALL
+ check_string = re.escape(")#")
+
+ if not pattern:
+ pattern = re.escape(self.base_prompt[:16])
+ pattern = f"{pattern}.*{check_string}"
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ output = self._send_command_str("bash", expect_string=r"[\$#]")
+ return output
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ output = self._send_command_str("exit", expect_string=r"[#>]")
+ return output
+
+
+class AristaSSH(AristaBase):
+ pass
+
+
+class AristaTelnet(AristaBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class AristaFileTransfer(CiscoFileTransfer):
+ """Arista SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/mnt/flash",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} file:{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=600)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class AristaBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AristaBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ # Arista will echo immediately and then when the device really responds (like NX-OS)
+ self.set_terminal_width(command=cmd, pattern=r"Width set to")
+ self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled")
+ self.set_base_prompt()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Arista, unfortunately, does this:
+ loc1-core01(s1)#
+
+ Can also be (s2)
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ output = output.replace("(s1)", "")
+ output = output.replace("(s2)", "")
+ return check_string in output
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Force arista to read pattern all the way to prompt on the next line."""
+
+ if not re_flags:
+ re_flags = re.DOTALL
+ check_string = re.escape(")#")
+
+ if not pattern:
+ pattern = re.escape(self.base_prompt[:16])
+ pattern = f"{pattern}.*{check_string}"
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ output = self._send_command_str("bash", expect_string=r"[\$#]")
+ return output
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ output = self._send_command_str("exit", expect_string=r"[#>]")
+ return output
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=')#', pattern='[>\\#]')
+
+-
+
Checks if the device is in configuration mode or not.
+Arista, unfortunately, does this:
+loc1-core01(s1)#
+Can also be (s2)
+
+Source code
+def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Arista, unfortunately, does this:
+ loc1-core01(s1)#
+
+ Can also be (s2)
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ output = output.replace("(s1)", "")
+ output = output.replace("(s2)", "")
+ return check_string in output
+
+
+
+def config_mode(self, config_command='configure terminal', pattern='', re_flags=0)
+
+-
+
Force arista to read pattern all the way to prompt on the next line.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+) -> str:
+ """Force arista to read pattern all the way to prompt on the next line."""
+
+ if not re_flags:
+ re_flags = re.DOTALL
+ check_string = re.escape(")#")
+
+ if not pattern:
+ pattern = re.escape(self.base_prompt[:16])
+ pattern = f"{pattern}.*{check_string}"
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ # Arista will echo immediately and then when the device really responds (like NX-OS)
+ self.set_terminal_width(command=cmd, pattern=r"Width set to")
+ self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled")
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class AristaFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/mnt/flash', direction='put', **kwargs)
+
+-
+
Arista SCP File Transfer driver.
+
+Source code
+class AristaFileTransfer(CiscoFileTransfer):
+ """Arista SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/mnt/flash",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} file:{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=600)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+class AristaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AristaSSH(AristaBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class AristaTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AristaTelnet(AristaBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/arista/index.html b/docs/netmiko/arista/index.html
new file mode 100644
index 000000000..6fb17e5a0
--- /dev/null
+++ b/docs/netmiko/arista/index.html
@@ -0,0 +1,524 @@
+
+
+
+
+
+
+netmiko.arista API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.arista.arista import AristaSSH, AristaTelnet, AristaFileTransfer
+
+__all__ = ["AristaSSH", "AristaTelnet", "AristaFileTransfer"]
+
+
+
+
+
+
+
+
+
+class AristaFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/mnt/flash', direction='put', **kwargs)
+
+-
+
Arista SCP File Transfer driver.
+
+Source code
+class AristaFileTransfer(CiscoFileTransfer):
+ """Arista SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/mnt/flash",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} file:{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=600)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+class AristaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AristaSSH(AristaBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class AristaTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class AristaTelnet(AristaBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/aruba/aruba_ssh.html b/docs/netmiko/aruba/aruba_ssh.html
new file mode 100644
index 000000000..68912a967
--- /dev/null
+++ b/docs/netmiko/aruba/aruba_ssh.html
@@ -0,0 +1,385 @@
+
+
+
+
+
+
+netmiko.aruba.aruba_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.aruba.aruba_ssh
+
+
+Aruba OS support.
+For use with Aruba OS Controllers.
+
+Source code
+"""
+Aruba OS support.
+
+For use with Aruba OS Controllers.
+
+"""
+from typing import Any
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ArubaSSH(CiscoSSHConnection):
+ """Aruba OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ # Aruba has an auto-complete on space behavior that is problematic
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Aruba OS requires enable mode to disable paging."""
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no page")
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Aruba uses "(<controller name>) (config) #" as config prompt
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+
+
+
+
+
+
+class ArubaSSH
+(**kwargs)
+
+-
+
Aruba OS support
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ArubaSSH(CiscoSSHConnection):
+ """Aruba OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ # Aruba has an auto-complete on space behavior that is problematic
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Aruba OS requires enable mode to disable paging."""
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no page")
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Aruba uses "(<controller name>) (config) #" as config prompt
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='(config) #', pattern='[>#]')
+
+-
+
Checks if the device is in configuration mode or not.
+Aruba uses "() (config) #" as config prompt
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Aruba uses "(<controller name>) (config) #" as config prompt
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def config_mode(self, config_command='configure term', pattern='', re_flags=0)
+
+-
+
Aruba auto completes on space so 'configure' needs fully spelled-out.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Aruba OS requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """Aruba OS requires enable mode to disable paging."""
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no page")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/aruba/index.html b/docs/netmiko/aruba/index.html
new file mode 100644
index 000000000..7419d6574
--- /dev/null
+++ b/docs/netmiko/aruba/index.html
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+netmiko.aruba API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.aruba.aruba_ssh import ArubaSSH
+
+__all__ = ["ArubaSSH"]
+
+
+
+
+
+
+
+
+
+class ArubaSSH
+(**kwargs)
+
+-
+
Aruba OS support
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ArubaSSH(CiscoSSHConnection):
+ """Aruba OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ # Aruba has an auto-complete on space behavior that is problematic
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Aruba OS requires enable mode to disable paging."""
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no page")
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Aruba uses "(<controller name>) (config) #" as config prompt
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='(config) #', pattern='[>#]')
+
+-
+
Checks if the device is in configuration mode or not.
+Aruba uses "() (config) #" as config prompt
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Aruba uses "(<controller name>) (config) #" as config prompt
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def config_mode(self, config_command='configure term', pattern='', re_flags=0)
+
+-
+
Aruba auto completes on space so 'configure' needs fully spelled-out.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Aruba OS requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """Aruba OS requires enable mode to disable paging."""
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no page")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html
new file mode 100644
index 000000000..85508950e
--- /dev/null
+++ b/docs/netmiko/base_connection.html
@@ -0,0 +1,7381 @@
+
+
+
+
+
+
+netmiko.base_connection API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.base_connection
+
+
+Base connection class for netmiko
+Handles SSH connection and methods that are generically applicable to different
+platforms (Cisco and non-Cisco).
+Also defines methods that should generally be supported by child classes
+
+Source code
+"""
+Base connection class for netmiko
+
+Handles SSH connection and methods that are generically applicable to different
+platforms (Cisco and non-Cisco).
+
+Also defines methods that should generally be supported by child classes
+"""
+from typing import (
+ Optional,
+ Callable,
+ Any,
+ List,
+ Dict,
+ TypeVar,
+ cast,
+ Type,
+ Sequence,
+ TextIO,
+ Union,
+ Tuple,
+ Deque,
+)
+from typing import TYPE_CHECKING
+from types import TracebackType
+import io
+import re
+import socket
+import telnetlib
+import time
+from collections import deque
+from os import path
+from threading import Lock
+import functools
+import logging
+
+import paramiko
+import serial
+from tenacity import retry, stop_after_attempt, wait_exponential
+import warnings
+
+from netmiko import log
+from netmiko.netmiko_globals import BACKSPACE_CHAR
+from netmiko.exceptions import (
+ NetmikoTimeoutException,
+ NetmikoAuthenticationException,
+ ConfigInvalidException,
+ ReadException,
+ ReadTimeout,
+)
+from netmiko.channel import Channel, SSHChannel, TelnetChannel, SerialChannel
+from netmiko.session_log import SessionLog
+from netmiko.utilities import (
+ write_bytes,
+ check_serial_port,
+ structured_data_converter,
+ run_ttp_template,
+ select_cmd_verify,
+ calc_old_timeout,
+)
+from netmiko.utilities import m_exec_time # noqa
+
+if TYPE_CHECKING:
+ from os import PathLike
+
+# For decorators
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+DELAY_FACTOR_DEPR_SIMPLE_MSG = """\n
+Netmiko 4.x and later has deprecated the use of delay_factor and/or
+max_loops in this context. You should remove any use of delay_factor=x
+from this method call.\n"""
+
+
+# Logging filter for #2597
+class SecretsFilter(logging.Filter):
+ def __init__(self, no_log: Optional[Dict[Any, str]] = None) -> None:
+ self.no_log = no_log
+
+ def filter(self, record: logging.LogRecord) -> bool:
+ """Removes secrets (no_log) from messages"""
+ if self.no_log:
+ for hidden_data in self.no_log.values():
+ record.msg = record.msg.replace(hidden_data, "********")
+ return True
+
+
+def lock_channel(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ self._lock_netmiko_session()
+ try:
+ return_val = func(self, *args, **kwargs)
+ finally:
+ # Always unlock the channel, even on exception.
+ self._unlock_netmiko_session()
+ return return_val
+
+ return cast(F, wrapper_decorator)
+
+
+def log_writes(func: F) -> F:
+ """Handle both session_log and log of writes."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", out_data: str) -> None:
+ func(self, out_data)
+ try:
+ log.debug(
+ "write_channel: {}".format(
+ str(write_bytes(out_data, encoding=self.encoding))
+ )
+ )
+ if self.session_log:
+ if self.session_log.fin or self.session_log.record_writes:
+ self.session_log.write(out_data)
+ except UnicodeDecodeError:
+ # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
+ pass
+ return None
+
+ return cast(F, wrapper_decorator)
+
+
+class BaseConnection:
+ """
+ Defines vendor independent methods.
+
+ Otherwise method left as a stub method.
+ """
+
+ def __init__(
+ self,
+ ip: str = "",
+ host: str = "",
+ username: str = "",
+ password: Optional[str] = None,
+ secret: str = "",
+ port: Optional[int] = None,
+ device_type: str = "",
+ verbose: bool = False,
+ global_delay_factor: float = 1.0,
+ global_cmd_verify: Optional[bool] = None,
+ use_keys: bool = False,
+ key_file: Optional[str] = None,
+ pkey: Optional[paramiko.PKey] = None,
+ passphrase: Optional[str] = None,
+ disabled_algorithms: Optional[Dict[str, Any]] = None,
+ allow_agent: bool = False,
+ ssh_strict: bool = False,
+ system_host_keys: bool = False,
+ alt_host_keys: bool = False,
+ alt_key_file: str = "",
+ ssh_config_file: Optional[str] = None,
+ #
+ # Connect timeouts
+ # ssh-connect --> TCP conn (conn_timeout) --> SSH-banner (banner_timeout)
+ # --> Auth response (auth_timeout)
+ conn_timeout: int = 10,
+ # Timeout to wait for authentication response
+ auth_timeout: Optional[int] = None,
+ banner_timeout: int = 15, # Timeout to wait for the banner to be presented
+ # Other timeouts
+ blocking_timeout: int = 20, # Read blocking timeout
+ timeout: int = 100, # TCP connect timeout | overloaded to read-loop timeout
+ session_timeout: int = 60, # Used for locking/sharing the connection
+ read_timeout_override: Optional[float] = None,
+ keepalive: int = 0,
+ default_enter: Optional[str] = None,
+ response_return: Optional[str] = None,
+ serial_settings: Optional[Dict[str, Any]] = None,
+ fast_cli: bool = True,
+ _legacy_mode: bool = False,
+ session_log: Optional[SessionLog] = None,
+ session_log_record_writes: bool = False,
+ session_log_file_mode: str = "write",
+ allow_auto_change: bool = False,
+ encoding: str = "ascii",
+ sock: Optional[socket.socket] = None,
+ auto_connect: bool = True,
+ delay_factor_compat: bool = False,
+ ) -> None:
+ """
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default: \n).
+
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default: \n)
+
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+ """
+
+ self.remote_conn: Union[
+ None, telnetlib.Telnet, paramiko.Channel, serial.Serial
+ ] = None
+ # Does the platform support a configuration mode
+ self._config_mode = True
+ self._read_buffer = ""
+ self.delay_factor_compat = delay_factor_compat
+
+ self.TELNET_RETURN = "\r\n"
+ if default_enter is None:
+ if "telnet" not in device_type:
+ self.RETURN = "\n"
+ else:
+ self.RETURN = self.TELNET_RETURN
+ else:
+ self.RETURN = default_enter
+
+ # Line Separator in response lines
+ self.RESPONSE_RETURN = "\n" if response_return is None else response_return
+ if ip:
+ self.host = ip.strip()
+ elif host:
+ self.host = host.strip()
+ if not ip and not host and "serial" not in device_type:
+ raise ValueError("Either ip or host must be set")
+ if port is None:
+ if "telnet" in device_type:
+ port = 23
+ else:
+ port = 22
+ self.port = int(port)
+
+ self.username = username
+ self.password = password
+ self.secret = secret
+ self.device_type = device_type
+ self.ansi_escape_codes = False
+ self.verbose = verbose
+ self.auth_timeout = auth_timeout
+ self.banner_timeout = banner_timeout
+ self.blocking_timeout = blocking_timeout
+ self.conn_timeout = conn_timeout
+ self.session_timeout = session_timeout
+ self.timeout = timeout
+ self.read_timeout_override = read_timeout_override
+ self.keepalive = keepalive
+ self.allow_auto_change = allow_auto_change
+ self.encoding = encoding
+ self.sock = sock
+ self.fast_cli = fast_cli
+ self._legacy_mode = _legacy_mode
+ self.global_delay_factor = global_delay_factor
+ self.global_cmd_verify = global_cmd_verify
+ if self.fast_cli and self.global_delay_factor == 1:
+ self.global_delay_factor = 0.1
+ self.session_log = None
+ self._session_log_close = False
+
+ # prevent logging secret data
+ no_log = {}
+ if self.password:
+ no_log["password"] = self.password
+ if self.secret:
+ no_log["secret"] = self.secret
+ log.addFilter(SecretsFilter(no_log=no_log))
+
+ # Netmiko will close the session_log if we open the file
+ if session_log is not None:
+ if isinstance(session_log, str):
+ # If session_log is a string, open a file corresponding to string name.
+ self.session_log = SessionLog(
+ file_name=session_log,
+ file_mode=session_log_file_mode,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ self.session_log.open()
+ elif isinstance(session_log, io.BufferedIOBase):
+ # In-memory buffer or an already open file handle
+ self.session_log = SessionLog(
+ buffered_io=session_log,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ else:
+ raise ValueError(
+ "session_log must be a path to a file, a file handle, "
+ "or a BufferedIOBase subclass."
+ )
+
+ # Default values
+ self.serial_settings = {
+ "port": "COM1",
+ "baudrate": 9600,
+ "bytesize": serial.EIGHTBITS,
+ "parity": serial.PARITY_NONE,
+ "stopbits": serial.STOPBITS_ONE,
+ }
+ if serial_settings is None:
+ serial_settings = {}
+ self.serial_settings.update(serial_settings)
+
+ if "serial" in device_type:
+ self.host = "serial"
+ comm_port = self.serial_settings.pop("port")
+ # Get the proper comm port reference if a name was enterred
+ comm_port = check_serial_port(comm_port)
+ self.serial_settings.update({"port": comm_port})
+
+ # set in set_base_prompt method
+ self.base_prompt = ""
+ self._session_locker = Lock()
+
+ # determine if telnet or SSH
+ if "_telnet" in device_type:
+ self.protocol = "telnet"
+ self.password = password or ""
+ elif "_serial" in device_type:
+ self.protocol = "serial"
+ self.password = password or ""
+ else:
+ self.protocol = "ssh"
+
+ self.key_policy: paramiko.client.MissingHostKeyPolicy
+ if not ssh_strict:
+ self.key_policy = paramiko.AutoAddPolicy()
+ else:
+ self.key_policy = paramiko.RejectPolicy()
+
+ # Options for SSH host_keys
+ self.use_keys = use_keys
+ self.key_file = (
+ path.abspath(path.expanduser(key_file)) if key_file else None
+ )
+ self.pkey = pkey
+ self.passphrase = passphrase
+ self.allow_agent = allow_agent
+ self.system_host_keys = system_host_keys
+ self.alt_host_keys = alt_host_keys
+ self.alt_key_file = alt_key_file
+ self.disabled_algorithms = disabled_algorithms or {}
+
+ # For SSH proxy support
+ self.ssh_config_file = ssh_config_file
+
+ # Establish the remote connection
+ if auto_connect:
+ self._open()
+
+ def _open(self) -> None:
+ """Decouple connection creation from __init__ for mocking."""
+ self._modify_connection_params()
+ self.establish_connection()
+ self._try_session_preparation()
+
+ def __enter__(self) -> "BaseConnection":
+ """Establish a session using a Context Manager."""
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ """Gracefully close connection on Context Manager exit."""
+ self.disconnect()
+
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ pass
+
+ def _timeout_exceeded(self, start: float, msg: str = "Timeout exceeded!") -> bool:
+ """Raise NetmikoTimeoutException if waiting too much in the serving queue.
+
+ :param start: Initial start time to see if session lock timeout has been exceeded
+ :type start: float (from time.time() call i.e. epoch time)
+
+ :param msg: Exception message if timeout was exceeded
+ :type msg: str
+ """
+ if not start:
+ # Must provide a comparison time
+ return False
+ if time.time() - start > self.session_timeout:
+ # session_timeout exceeded
+ raise NetmikoTimeoutException(msg)
+ return False
+
+ def _lock_netmiko_session(self, start: Optional[float] = None) -> bool:
+ """Try to acquire the Netmiko session lock. If not available, wait in the queue until
+ the channel is available again.
+
+ :param start: Initial start time to measure the session timeout
+ :type start: float (from time.time() call i.e. epoch time)
+ """
+ if not start:
+ start = time.time()
+ # Wait here until the SSH channel lock is acquired or until session_timeout exceeded
+ while not self._session_locker.acquire(False) and not self._timeout_exceeded(
+ start, "The netmiko channel is not available!"
+ ):
+ time.sleep(0.1)
+ return True
+
+ def _unlock_netmiko_session(self) -> None:
+ """
+ Release the channel at the end of the task.
+ """
+ if self._session_locker.locked():
+ self._session_locker.release()
+
+ def _autodetect_fs(self, cmd: str = "", pattern: str = "") -> str:
+ raise NotImplementedError
+
+ def _enter_shell(self) -> str:
+ raise NotImplementedError
+
+ def _return_cli(self) -> str:
+ raise NotImplementedError
+
+ @lock_channel
+ @log_writes
+ def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
+
+ :param out_data: data to be written to the channel
+ :type out_data: str
+ """
+ self.channel.write_channel(out_data)
+
+ def is_alive(self) -> bool:
+ """Returns a boolean flag with the state of the connection."""
+ null = chr(0)
+ if self.remote_conn is None:
+ log.error("Connection is not initialised, is_alive returns False")
+ return False
+ if self.protocol == "telnet":
+ try:
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
+ log.debug("Sending IAC + NOP")
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
+ except AttributeError:
+ return False
+ else:
+ # SSH
+ try:
+ # Try sending ASCII null byte to maintain the connection alive
+ log.debug("Sending the NULL byte")
+ self.write_channel(null)
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
+ except (socket.error, EOFError):
+ log.error("Unable to send", exc_info=True)
+ # If unable to send, we can tell for sure that the connection is unusable
+ return False
+ return False
+
+ @lock_channel
+ def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
+ return output
+
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
+
+ Will return string up to and including pattern.
+
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
+
+ :param pattern: Regular expression pattern used to identify that reading is done.
+
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
+
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
+ return output
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
+
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read data on the channel based on timing delays.
+
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
+
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
+
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
+ channel_data = ""
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+ # gather new output
+ if new_data:
+ channel_data += new_data
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
+ new_data = self.read_channel()
+ if not new_data:
+ break
+ else:
+ channel_data += new_data
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
+
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
+
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
+
+You can look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+ return channel_data
+
+ def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
+ if pattern:
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login. Can be username/password or just password.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param username_pattern: Pattern used to identify the username prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param max_loops: Controls the wait time in conjunction with the delay_factor
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+ def _try_session_preparation(self) -> None:
+ """
+ In case of an exception happening during `session_preparation()` Netmiko should
+ gracefully clean-up after itself. This might be challenging for library users
+ to do since they do not have a reference to the object. This is possibly related
+ to threads used in Paramiko.
+ """
+ try:
+ self.session_preparation()
+ except Exception:
+ self.disconnect()
+ raise
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some differences that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self._test_channel_read(pattern=r"some_pattern")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def _use_ssh_config(self, dict_arg: Dict[str, Any]) -> Dict[str, Any]:
+ """Update SSH connection parameters based on contents of SSH config file.
+
+ :param dict_arg: Dictionary of SSH connection parameters
+ """
+ connect_dict = dict_arg.copy()
+
+ # Use SSHConfig to generate source content.
+ assert self.ssh_config_file is not None
+ full_path = path.abspath(path.expanduser(self.ssh_config_file))
+ source: Union[paramiko.config.SSHConfigDict, Dict[str, Any]]
+ if path.exists(full_path):
+ ssh_config_instance = paramiko.SSHConfig()
+ with io.open(full_path, "rt", encoding="utf-8") as f:
+ ssh_config_instance.parse(f)
+ source = ssh_config_instance.lookup(self.host)
+ else:
+ source = {}
+
+ # Keys get normalized to lower-case
+ proxy: Optional[paramiko.proxy.ProxyCommand]
+ if "proxycommand" in source:
+ proxy = paramiko.ProxyCommand(source["proxycommand"])
+ elif "proxyjump" in source:
+ hops = list(reversed(source["proxyjump"].split(",")))
+ if len(hops) > 1:
+ raise ValueError(
+ "ProxyJump with more than one proxy server is not supported."
+ )
+ port = source.get("port", self.port)
+ host = source.get("hostname", self.host)
+ # -F {full_path} forces the continued use of the same SSH config file
+ cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0])
+ proxy = paramiko.ProxyCommand(cmd)
+ else:
+ proxy = None
+
+ # Only update 'hostname', 'sock', 'port', and 'username'
+ # For 'port' and 'username' only update if using object defaults
+ if connect_dict["port"] == 22:
+ connect_dict["port"] = int(source.get("port", self.port))
+ if connect_dict["username"] == "":
+ connect_dict["username"] = source.get("user", self.username)
+ if proxy:
+ connect_dict["sock"] = proxy
+ connect_dict["hostname"] = source.get("hostname", self.host)
+
+ return connect_dict
+
+ def _connect_params_dict(self) -> Dict[str, Any]:
+ """Generate dictionary of Paramiko connection parameters."""
+ conn_dict = {
+ "hostname": self.host,
+ "port": self.port,
+ "username": self.username,
+ "password": self.password,
+ "look_for_keys": self.use_keys,
+ "allow_agent": self.allow_agent,
+ "key_filename": self.key_file,
+ "pkey": self.pkey,
+ "passphrase": self.passphrase,
+ "disabled_algorithms": self.disabled_algorithms,
+ "timeout": self.conn_timeout,
+ "auth_timeout": self.auth_timeout,
+ "banner_timeout": self.banner_timeout,
+ "sock": self.sock,
+ }
+
+ # Check if using SSH 'config' file mainly for SSH proxy support
+ if self.ssh_config_file:
+ conn_dict = self._use_ssh_config(conn_dict)
+ return conn_dict
+
+ def _sanitize_output(
+ self,
+ output: str,
+ strip_command: bool = False,
+ command_string: Optional[str] = None,
+ strip_prompt: bool = False,
+ ) -> str:
+ """Strip out command echo and trailing router prompt."""
+ if strip_command and command_string:
+ command_string = self.normalize_linefeeds(command_string)
+ output = self.strip_command(command_string, output)
+ if strip_prompt:
+ output = self.strip_prompt(output)
+ return output
+
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
+ """Establish SSH connection to the network device
+
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
+
+ :param width: Specified width of the VT100 terminal window (default: 511)
+ :type width: int
+
+ :param height: Specified height of the VT100 terminal window (default: 1000)
+ :type height: int
+ """
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.telnet_login()
+ elif self.protocol == "serial":
+ self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.serial_login()
+ elif self.protocol == "ssh":
+ ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
+ self.remote_conn_pre = self._build_ssh_client()
+
+ # initiate SSH connection
+ try:
+ self.remote_conn_pre.connect(**ssh_connect_params)
+ except socket.error as conn_error:
+ self.paramiko_cleanup()
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
+ except paramiko.ssh_exception.AuthenticationException as auth_err:
+ self.paramiko_cleanup()
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ msg += self.RETURN + str(auth_err)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
+
+ if self.verbose:
+ print(f"SSH connection established to {self.host}:{self.port}")
+
+ # Use invoke_shell to establish an 'interactive session'
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
+
+ self.remote_conn.settimeout(self.blocking_timeout)
+ if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
+ self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
+ self.special_login_handler()
+ if self.verbose:
+ print("Interactive SSH session established")
+
+ return None
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Try to read the channel (generally post login) verify you receive data back.
+
+ :param count: the number of times to check the channel for data
+
+ :param pattern: Regular expression pattern used to determine end of channel read
+ """
+
+ def _increment_delay(
+ main_delay: float, increment: float = 1.1, maximum: int = 8
+ ) -> float:
+ """Increment sleep time to a maximum value."""
+ main_delay = main_delay * increment
+ if main_delay >= maximum:
+ main_delay = maximum
+ return main_delay
+
+ i = 0
+ delay_factor = self.select_delay_factor(delay_factor=0)
+
+ if pattern:
+ return self.read_until_pattern(pattern=pattern, read_timeout=20)
+
+ main_delay = delay_factor * 0.1
+ time.sleep(main_delay * 10)
+ new_data = ""
+ while i <= count:
+ new_data += self.read_channel_timing()
+ if new_data:
+ return new_data
+
+ self.write_channel(self.RETURN)
+ main_delay = _increment_delay(main_delay)
+ time.sleep(main_delay)
+ i += 1
+
+ raise NetmikoTimeoutException("Timed out waiting for data")
+
+ def _build_ssh_client(self) -> paramiko.SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ remote_conn_pre = paramiko.SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def select_delay_factor(self, delay_factor: float) -> float:
+ """
+ Choose the greater of delay_factor or self.global_delay_factor (default).
+ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+ """
+ if self.fast_cli:
+ if delay_factor and delay_factor <= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+ else:
+ if delay_factor >= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
+ pass
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging default to a Cisco CLI method.
+
+ :param command: Device command to disable pagination of output
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
+ log.debug("Exiting disable_paging")
+ return output
+
+ def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """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
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if not command:
+ return ""
+ command = self.normalize_cmd(command)
+ self.write_channel(command)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
+ return output
+
+ # 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),
+ reraise=True,
+ )
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Cisco
+ devices this will be set to router hostname (i.e. prompt without > or #).
+
+ This will be set on entering user exec or privileged exec on Cisco, but not when
+ entering/exiting config mode.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
+ """
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
+ if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
+ # Strip off trailing terminator
+ self.base_prompt = prompt[:-1]
+ return self.base_prompt
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ """Finds the current network device prompt, last line only.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
+ self.clear_buffer()
+ self.write_channel(self.RETURN)
+
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
+
+ # If multiple lines in the output take the last line
+ prompt = prompt.split(self.RESPONSE_RETURN)[-1]
+ prompt = prompt.strip()
+ self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
+ return prompt
+
+ def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """Read any data available in the channel."""
+
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+ def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+ @select_cmd_verify
+ def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a delay-based mechanism. Generally
+ used for show commands.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
+ """
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+ self.write_channel(command_string)
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+ def _send_command_timing_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command_timing` method that always returns a
+ string"""
+ output = self.send_command_timing(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ :param a_string: Returned string from device
+ :type a_string: str
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ if self.base_prompt in last_line:
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def _first_line_handler(self, data: str, search_pattern: str) -> Tuple[str, bool]:
+ """
+ In certain situations the first line will get repainted which causes a false
+ match on the terminating pattern.
+
+ Filter this out.
+
+ returns a tuple of (data, first_line_processed)
+
+ Where data is the original data potentially with the first line modified
+ and the first_line_processed is a flag indicating that we have handled the
+ first line.
+ """
+ try:
+ # First line is the echo line containing the command. In certain situations
+ # it gets repainted and needs filtered
+ lines = data.split(self.RETURN)
+ first_line = lines[0]
+ if BACKSPACE_CHAR in first_line:
+ pattern = search_pattern + r".*$"
+ first_line = re.sub(pattern, repl="", string=first_line)
+ lines[0] = first_line
+ data = self.RETURN.join(lines)
+ return (data, True)
+ except IndexError:
+ return (data, False)
+
+ def _prompt_handler(self, auto_find_prompt: bool) -> str:
+ if auto_find_prompt:
+ try:
+ prompt = self.find_prompt()
+ except ValueError:
+ prompt = self.base_prompt
+ else:
+ prompt = self.base_prompt
+ return re.escape(prompt.strip())
+
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+ used for show commands. By default this method will keep waiting to receive data until the
+ network device prompt is detected. The current network device prompt will be determined
+ automatically.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param expect_string: Regular expression pattern to use for determining end of output.
+ If left blank will default to being based on router prompt.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
+ """
+
+ # Time to delay in each read loop
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
+ else:
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
+ else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
+ search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
+
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+
+ # Start the clock
+ start_time = time.time()
+ self.write_channel(command_string)
+ new_data = ""
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
+ if new_data:
+ output += new_data
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
+ if re.search(search_pattern, output):
+ break
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+ def _send_command_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command` method that always returns a string"""
+ output = self.send_command(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def send_command_expect(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+ def _multiline_kwargs(self, **kwargs: Any) -> Dict[str, Any]:
+ strip_prompt = kwargs.get("strip_prompt", False)
+ kwargs["strip_prompt"] = strip_prompt
+ strip_command = kwargs.get("strip_command", False)
+ kwargs["strip_command"] = strip_command
+ return kwargs
+
+ def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """
+ commands should either be:
+
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
+
+ """
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+ def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+ ) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
+
+ @staticmethod
+ def strip_backspaces(output: str) -> str:
+ """Strip any backspace characters out of the output.
+
+ :param output: Output obtained from a remote network device.
+ :type output: str
+ """
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """
+ Strip command_string from output string
+
+ Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+
+ :param command_string: The command string sent to the device
+ :type command_string: str
+
+ :param output: The returned output as a result of the command string sent to the device
+ :type output: str
+ """
+ backspace_char = "\x08"
+
+ # Check for line wrap (remove backspaces)
+ if backspace_char in output:
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
+ output_lines = output.split(self.RESPONSE_RETURN)
+ new_output = output_lines[1:]
+ return self.RESPONSE_RETURN.join(new_output)
+ else:
+ # command_string isn't there; do nothing
+ return output
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
+
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+ """
+ newline = re.compile("(\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":
+ # Convert any remaining \r to \n
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
+
+ def normalize_cmd(self, command: str) -> str:
+ """Normalize CLI commands to have a single trailing newline.
+
+ :param command: Command that may require line feed to be normalized
+ :type command: str
+ """
+ command = command.rstrip()
+ command += self.RETURN
+ return command
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ """Check if in enable mode. Return boolean.
+
+ :param check_string: Identification of privilege mode from device
+ :type check_string: str
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode.
+
+ :param cmd: Device command to enter enable mode
+
+ :param pattern: pattern to search for indicating device is waiting for password
+
+ :param enable_pattern: pattern indicating you have entered enable mode
+
+ :param re_flags: Regular expression flags used in conjunction with pattern
+ """
+ output = ""
+ msg = (
+ "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:
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ """Exit enable mode.
+
+ :param exit_command: Command that exits the session from privileged mode
+ :type exit_command: str
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ output += self.read_until_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ :param check_string: Identification of configuration mode from the device
+ :type check_string: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ 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)
+ return check_string in output
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode.
+
+ :param config_command: Configuration command to send to the device
+ :type config_command: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
+ """
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ """Exit from configuration mode.
+
+ :param exit_config: Command to exit configuration mode
+ :type exit_config: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel from a file.
+
+ The file is processed line-by-line and each command is sent down the
+ SSH channel.
+
+ **kwargs are passed to send_config_set method.
+
+ :param config_file: Path to configuration file to be sent to the device
+
+ :param kwargs: params to be sent to send_config_set method
+ """
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel.
+
+ config_commands is an iterable containing all of the configuration commands.
+ The commands will be executed one after the other.
+
+ Automatically exits/enters configuration mode.
+
+ :param config_commands: Multiple configuration commands to be sent to the device
+
+ :param exit_config_mode: Determines whether or not to exit config mode after complete
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Determines whether or not to strip the prompt
+
+ :param strip_command: Determines whether or not to strip the command
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+
+ :param config_mode_command: The command to enter into config mode
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
+ """
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
+ if config_commands is None:
+ return ""
+ elif isinstance(config_commands, str):
+ config_commands = (config_commands,)
+
+ if not hasattr(config_commands, "__iter__"):
+ raise ValueError("Invalid argument passed into send_config_set")
+
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
+ # Send config commands
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
+ log.debug(f"{output}")
+ return output
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Remove any ANSI (VT100) ESC codes from the output
+
+ http://en.wikipedia.org/wiki/ANSI_escape_code
+
+ Note: this does not capture ALL possible ANSI Escape Codes only the ones
+ I have encountered
+
+ Current codes that are filtered:
+ ESC = '\x1b' or chr(27)
+ ESC = is the escape character [^ in hex ('\x1b')
+ ESC[24;27H Position cursor
+ ESC[?25h Show the cursor
+ ESC[E Next line (HP does ESC-E)
+ ESC[K Erase line from cursor to the end of line
+ ESC[2K Erase entire line
+ ESC[1;24r Enable scrolling from start to row end
+ ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
+ ESC[?7l Disable line wrapping
+ ESC[2J Code erase display
+ ESC[00;32m Color Green (30 to 37 are different colors)
+ ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
+
+ HP ProCurve and Cisco SG300 require this (possible others).
+
+ :param string_buffer: The string to be processed to remove ANSI escape codes
+ :type string_buffer: str
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
+
+ output = string_buffer
+ for ansi_esc_code in code_set:
+ output = re.sub(ansi_esc_code, "", output)
+
+ # CODE_NEXT_LINE must substitute with return
+ output = re.sub(code_next_line, self.RETURN, output)
+
+ # Aruba and ProCurve switches can use code_insert_line for <enter>
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new <enter>
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
+
+ return output
+
+ def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
+ pass
+
+ def paramiko_cleanup(self) -> None:
+ """Cleanup Paramiko to try to gracefully handle SSH session ending."""
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
+ del self.remote_conn_pre
+
+ def disconnect(self) -> None:
+ """Try to gracefully close the session."""
+ try:
+ self.cleanup()
+ if self.protocol == "ssh":
+ self.paramiko_cleanup()
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ self.remote_conn.close()
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
+ self.remote_conn.close()
+ except Exception:
+ # There have been race conditions observed on disconnect.
+ pass
+ finally:
+ self.remote_conn_pre = None
+ self.remote_conn = None
+ if self.session_log:
+ self.session_log.close()
+
+ def commit(self) -> str:
+ """Commit method for platforms that support this."""
+ raise AttributeError("Network device does not support 'commit()' method")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def run_ttp(
+ self,
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+ ) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
+
+class TelnetConnection(BaseConnection):
+ pass
+
+
+
+
+
+
+
+
+def lock_channel(func)
+
+-
+
+
+Source code
+def lock_channel(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ self._lock_netmiko_session()
+ try:
+ return_val = func(self, *args, **kwargs)
+ finally:
+ # Always unlock the channel, even on exception.
+ self._unlock_netmiko_session()
+ return return_val
+
+ return cast(F, wrapper_decorator)
+
+
+
+def log_writes(func)
+
+-
+
Handle both session_log and log of writes.
+
+Source code
+def log_writes(func: F) -> F:
+ """Handle both session_log and log of writes."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", out_data: str) -> None:
+ func(self, out_data)
+ try:
+ log.debug(
+ "write_channel: {}".format(
+ str(write_bytes(out_data, encoding=self.encoding))
+ )
+ )
+ if self.session_log:
+ if self.session_log.fin or self.session_log.record_writes:
+ self.session_log.write(out_data)
+ except UnicodeDecodeError:
+ # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
+ pass
+ return None
+
+ return cast(F, wrapper_decorator)
+
+
+
+
+
+
+
+
+class BaseConnection
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class BaseConnection:
+ """
+ Defines vendor independent methods.
+
+ Otherwise method left as a stub method.
+ """
+
+ def __init__(
+ self,
+ ip: str = "",
+ host: str = "",
+ username: str = "",
+ password: Optional[str] = None,
+ secret: str = "",
+ port: Optional[int] = None,
+ device_type: str = "",
+ verbose: bool = False,
+ global_delay_factor: float = 1.0,
+ global_cmd_verify: Optional[bool] = None,
+ use_keys: bool = False,
+ key_file: Optional[str] = None,
+ pkey: Optional[paramiko.PKey] = None,
+ passphrase: Optional[str] = None,
+ disabled_algorithms: Optional[Dict[str, Any]] = None,
+ allow_agent: bool = False,
+ ssh_strict: bool = False,
+ system_host_keys: bool = False,
+ alt_host_keys: bool = False,
+ alt_key_file: str = "",
+ ssh_config_file: Optional[str] = None,
+ #
+ # Connect timeouts
+ # ssh-connect --> TCP conn (conn_timeout) --> SSH-banner (banner_timeout)
+ # --> Auth response (auth_timeout)
+ conn_timeout: int = 10,
+ # Timeout to wait for authentication response
+ auth_timeout: Optional[int] = None,
+ banner_timeout: int = 15, # Timeout to wait for the banner to be presented
+ # Other timeouts
+ blocking_timeout: int = 20, # Read blocking timeout
+ timeout: int = 100, # TCP connect timeout | overloaded to read-loop timeout
+ session_timeout: int = 60, # Used for locking/sharing the connection
+ read_timeout_override: Optional[float] = None,
+ keepalive: int = 0,
+ default_enter: Optional[str] = None,
+ response_return: Optional[str] = None,
+ serial_settings: Optional[Dict[str, Any]] = None,
+ fast_cli: bool = True,
+ _legacy_mode: bool = False,
+ session_log: Optional[SessionLog] = None,
+ session_log_record_writes: bool = False,
+ session_log_file_mode: str = "write",
+ allow_auto_change: bool = False,
+ encoding: str = "ascii",
+ sock: Optional[socket.socket] = None,
+ auto_connect: bool = True,
+ delay_factor_compat: bool = False,
+ ) -> None:
+ """
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default: \n).
+
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default: \n)
+
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+ """
+
+ self.remote_conn: Union[
+ None, telnetlib.Telnet, paramiko.Channel, serial.Serial
+ ] = None
+ # Does the platform support a configuration mode
+ self._config_mode = True
+ self._read_buffer = ""
+ self.delay_factor_compat = delay_factor_compat
+
+ self.TELNET_RETURN = "\r\n"
+ if default_enter is None:
+ if "telnet" not in device_type:
+ self.RETURN = "\n"
+ else:
+ self.RETURN = self.TELNET_RETURN
+ else:
+ self.RETURN = default_enter
+
+ # Line Separator in response lines
+ self.RESPONSE_RETURN = "\n" if response_return is None else response_return
+ if ip:
+ self.host = ip.strip()
+ elif host:
+ self.host = host.strip()
+ if not ip and not host and "serial" not in device_type:
+ raise ValueError("Either ip or host must be set")
+ if port is None:
+ if "telnet" in device_type:
+ port = 23
+ else:
+ port = 22
+ self.port = int(port)
+
+ self.username = username
+ self.password = password
+ self.secret = secret
+ self.device_type = device_type
+ self.ansi_escape_codes = False
+ self.verbose = verbose
+ self.auth_timeout = auth_timeout
+ self.banner_timeout = banner_timeout
+ self.blocking_timeout = blocking_timeout
+ self.conn_timeout = conn_timeout
+ self.session_timeout = session_timeout
+ self.timeout = timeout
+ self.read_timeout_override = read_timeout_override
+ self.keepalive = keepalive
+ self.allow_auto_change = allow_auto_change
+ self.encoding = encoding
+ self.sock = sock
+ self.fast_cli = fast_cli
+ self._legacy_mode = _legacy_mode
+ self.global_delay_factor = global_delay_factor
+ self.global_cmd_verify = global_cmd_verify
+ if self.fast_cli and self.global_delay_factor == 1:
+ self.global_delay_factor = 0.1
+ self.session_log = None
+ self._session_log_close = False
+
+ # prevent logging secret data
+ no_log = {}
+ if self.password:
+ no_log["password"] = self.password
+ if self.secret:
+ no_log["secret"] = self.secret
+ log.addFilter(SecretsFilter(no_log=no_log))
+
+ # Netmiko will close the session_log if we open the file
+ if session_log is not None:
+ if isinstance(session_log, str):
+ # If session_log is a string, open a file corresponding to string name.
+ self.session_log = SessionLog(
+ file_name=session_log,
+ file_mode=session_log_file_mode,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ self.session_log.open()
+ elif isinstance(session_log, io.BufferedIOBase):
+ # In-memory buffer or an already open file handle
+ self.session_log = SessionLog(
+ buffered_io=session_log,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ else:
+ raise ValueError(
+ "session_log must be a path to a file, a file handle, "
+ "or a BufferedIOBase subclass."
+ )
+
+ # Default values
+ self.serial_settings = {
+ "port": "COM1",
+ "baudrate": 9600,
+ "bytesize": serial.EIGHTBITS,
+ "parity": serial.PARITY_NONE,
+ "stopbits": serial.STOPBITS_ONE,
+ }
+ if serial_settings is None:
+ serial_settings = {}
+ self.serial_settings.update(serial_settings)
+
+ if "serial" in device_type:
+ self.host = "serial"
+ comm_port = self.serial_settings.pop("port")
+ # Get the proper comm port reference if a name was enterred
+ comm_port = check_serial_port(comm_port)
+ self.serial_settings.update({"port": comm_port})
+
+ # set in set_base_prompt method
+ self.base_prompt = ""
+ self._session_locker = Lock()
+
+ # determine if telnet or SSH
+ if "_telnet" in device_type:
+ self.protocol = "telnet"
+ self.password = password or ""
+ elif "_serial" in device_type:
+ self.protocol = "serial"
+ self.password = password or ""
+ else:
+ self.protocol = "ssh"
+
+ self.key_policy: paramiko.client.MissingHostKeyPolicy
+ if not ssh_strict:
+ self.key_policy = paramiko.AutoAddPolicy()
+ else:
+ self.key_policy = paramiko.RejectPolicy()
+
+ # Options for SSH host_keys
+ self.use_keys = use_keys
+ self.key_file = (
+ path.abspath(path.expanduser(key_file)) if key_file else None
+ )
+ self.pkey = pkey
+ self.passphrase = passphrase
+ self.allow_agent = allow_agent
+ self.system_host_keys = system_host_keys
+ self.alt_host_keys = alt_host_keys
+ self.alt_key_file = alt_key_file
+ self.disabled_algorithms = disabled_algorithms or {}
+
+ # For SSH proxy support
+ self.ssh_config_file = ssh_config_file
+
+ # Establish the remote connection
+ if auto_connect:
+ self._open()
+
+ def _open(self) -> None:
+ """Decouple connection creation from __init__ for mocking."""
+ self._modify_connection_params()
+ self.establish_connection()
+ self._try_session_preparation()
+
+ def __enter__(self) -> "BaseConnection":
+ """Establish a session using a Context Manager."""
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ """Gracefully close connection on Context Manager exit."""
+ self.disconnect()
+
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ pass
+
+ def _timeout_exceeded(self, start: float, msg: str = "Timeout exceeded!") -> bool:
+ """Raise NetmikoTimeoutException if waiting too much in the serving queue.
+
+ :param start: Initial start time to see if session lock timeout has been exceeded
+ :type start: float (from time.time() call i.e. epoch time)
+
+ :param msg: Exception message if timeout was exceeded
+ :type msg: str
+ """
+ if not start:
+ # Must provide a comparison time
+ return False
+ if time.time() - start > self.session_timeout:
+ # session_timeout exceeded
+ raise NetmikoTimeoutException(msg)
+ return False
+
+ def _lock_netmiko_session(self, start: Optional[float] = None) -> bool:
+ """Try to acquire the Netmiko session lock. If not available, wait in the queue until
+ the channel is available again.
+
+ :param start: Initial start time to measure the session timeout
+ :type start: float (from time.time() call i.e. epoch time)
+ """
+ if not start:
+ start = time.time()
+ # Wait here until the SSH channel lock is acquired or until session_timeout exceeded
+ while not self._session_locker.acquire(False) and not self._timeout_exceeded(
+ start, "The netmiko channel is not available!"
+ ):
+ time.sleep(0.1)
+ return True
+
+ def _unlock_netmiko_session(self) -> None:
+ """
+ Release the channel at the end of the task.
+ """
+ if self._session_locker.locked():
+ self._session_locker.release()
+
+ def _autodetect_fs(self, cmd: str = "", pattern: str = "") -> str:
+ raise NotImplementedError
+
+ def _enter_shell(self) -> str:
+ raise NotImplementedError
+
+ def _return_cli(self) -> str:
+ raise NotImplementedError
+
+ @lock_channel
+ @log_writes
+ def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
+
+ :param out_data: data to be written to the channel
+ :type out_data: str
+ """
+ self.channel.write_channel(out_data)
+
+ def is_alive(self) -> bool:
+ """Returns a boolean flag with the state of the connection."""
+ null = chr(0)
+ if self.remote_conn is None:
+ log.error("Connection is not initialised, is_alive returns False")
+ return False
+ if self.protocol == "telnet":
+ try:
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
+ log.debug("Sending IAC + NOP")
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
+ except AttributeError:
+ return False
+ else:
+ # SSH
+ try:
+ # Try sending ASCII null byte to maintain the connection alive
+ log.debug("Sending the NULL byte")
+ self.write_channel(null)
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
+ except (socket.error, EOFError):
+ log.error("Unable to send", exc_info=True)
+ # If unable to send, we can tell for sure that the connection is unusable
+ return False
+ return False
+
+ @lock_channel
+ def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
+ return output
+
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
+
+ Will return string up to and including pattern.
+
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
+
+ :param pattern: Regular expression pattern used to identify that reading is done.
+
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
+
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
+ return output
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
+
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read data on the channel based on timing delays.
+
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
+
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
+
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
+ channel_data = ""
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+ # gather new output
+ if new_data:
+ channel_data += new_data
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
+ new_data = self.read_channel()
+ if not new_data:
+ break
+ else:
+ channel_data += new_data
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
+
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
+
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
+
+You can look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+ return channel_data
+
+ def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
+ if pattern:
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login. Can be username/password or just password.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param username_pattern: Pattern used to identify the username prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param max_loops: Controls the wait time in conjunction with the delay_factor
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+ def _try_session_preparation(self) -> None:
+ """
+ In case of an exception happening during `session_preparation()` Netmiko should
+ gracefully clean-up after itself. This might be challenging for library users
+ to do since they do not have a reference to the object. This is possibly related
+ to threads used in Paramiko.
+ """
+ try:
+ self.session_preparation()
+ except Exception:
+ self.disconnect()
+ raise
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some differences that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self._test_channel_read(pattern=r"some_pattern")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def _use_ssh_config(self, dict_arg: Dict[str, Any]) -> Dict[str, Any]:
+ """Update SSH connection parameters based on contents of SSH config file.
+
+ :param dict_arg: Dictionary of SSH connection parameters
+ """
+ connect_dict = dict_arg.copy()
+
+ # Use SSHConfig to generate source content.
+ assert self.ssh_config_file is not None
+ full_path = path.abspath(path.expanduser(self.ssh_config_file))
+ source: Union[paramiko.config.SSHConfigDict, Dict[str, Any]]
+ if path.exists(full_path):
+ ssh_config_instance = paramiko.SSHConfig()
+ with io.open(full_path, "rt", encoding="utf-8") as f:
+ ssh_config_instance.parse(f)
+ source = ssh_config_instance.lookup(self.host)
+ else:
+ source = {}
+
+ # Keys get normalized to lower-case
+ proxy: Optional[paramiko.proxy.ProxyCommand]
+ if "proxycommand" in source:
+ proxy = paramiko.ProxyCommand(source["proxycommand"])
+ elif "proxyjump" in source:
+ hops = list(reversed(source["proxyjump"].split(",")))
+ if len(hops) > 1:
+ raise ValueError(
+ "ProxyJump with more than one proxy server is not supported."
+ )
+ port = source.get("port", self.port)
+ host = source.get("hostname", self.host)
+ # -F {full_path} forces the continued use of the same SSH config file
+ cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0])
+ proxy = paramiko.ProxyCommand(cmd)
+ else:
+ proxy = None
+
+ # Only update 'hostname', 'sock', 'port', and 'username'
+ # For 'port' and 'username' only update if using object defaults
+ if connect_dict["port"] == 22:
+ connect_dict["port"] = int(source.get("port", self.port))
+ if connect_dict["username"] == "":
+ connect_dict["username"] = source.get("user", self.username)
+ if proxy:
+ connect_dict["sock"] = proxy
+ connect_dict["hostname"] = source.get("hostname", self.host)
+
+ return connect_dict
+
+ def _connect_params_dict(self) -> Dict[str, Any]:
+ """Generate dictionary of Paramiko connection parameters."""
+ conn_dict = {
+ "hostname": self.host,
+ "port": self.port,
+ "username": self.username,
+ "password": self.password,
+ "look_for_keys": self.use_keys,
+ "allow_agent": self.allow_agent,
+ "key_filename": self.key_file,
+ "pkey": self.pkey,
+ "passphrase": self.passphrase,
+ "disabled_algorithms": self.disabled_algorithms,
+ "timeout": self.conn_timeout,
+ "auth_timeout": self.auth_timeout,
+ "banner_timeout": self.banner_timeout,
+ "sock": self.sock,
+ }
+
+ # Check if using SSH 'config' file mainly for SSH proxy support
+ if self.ssh_config_file:
+ conn_dict = self._use_ssh_config(conn_dict)
+ return conn_dict
+
+ def _sanitize_output(
+ self,
+ output: str,
+ strip_command: bool = False,
+ command_string: Optional[str] = None,
+ strip_prompt: bool = False,
+ ) -> str:
+ """Strip out command echo and trailing router prompt."""
+ if strip_command and command_string:
+ command_string = self.normalize_linefeeds(command_string)
+ output = self.strip_command(command_string, output)
+ if strip_prompt:
+ output = self.strip_prompt(output)
+ return output
+
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
+ """Establish SSH connection to the network device
+
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
+
+ :param width: Specified width of the VT100 terminal window (default: 511)
+ :type width: int
+
+ :param height: Specified height of the VT100 terminal window (default: 1000)
+ :type height: int
+ """
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.telnet_login()
+ elif self.protocol == "serial":
+ self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.serial_login()
+ elif self.protocol == "ssh":
+ ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
+ self.remote_conn_pre = self._build_ssh_client()
+
+ # initiate SSH connection
+ try:
+ self.remote_conn_pre.connect(**ssh_connect_params)
+ except socket.error as conn_error:
+ self.paramiko_cleanup()
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
+ except paramiko.ssh_exception.AuthenticationException as auth_err:
+ self.paramiko_cleanup()
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ msg += self.RETURN + str(auth_err)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
+
+ if self.verbose:
+ print(f"SSH connection established to {self.host}:{self.port}")
+
+ # Use invoke_shell to establish an 'interactive session'
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
+
+ self.remote_conn.settimeout(self.blocking_timeout)
+ if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
+ self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
+ self.special_login_handler()
+ if self.verbose:
+ print("Interactive SSH session established")
+
+ return None
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Try to read the channel (generally post login) verify you receive data back.
+
+ :param count: the number of times to check the channel for data
+
+ :param pattern: Regular expression pattern used to determine end of channel read
+ """
+
+ def _increment_delay(
+ main_delay: float, increment: float = 1.1, maximum: int = 8
+ ) -> float:
+ """Increment sleep time to a maximum value."""
+ main_delay = main_delay * increment
+ if main_delay >= maximum:
+ main_delay = maximum
+ return main_delay
+
+ i = 0
+ delay_factor = self.select_delay_factor(delay_factor=0)
+
+ if pattern:
+ return self.read_until_pattern(pattern=pattern, read_timeout=20)
+
+ main_delay = delay_factor * 0.1
+ time.sleep(main_delay * 10)
+ new_data = ""
+ while i <= count:
+ new_data += self.read_channel_timing()
+ if new_data:
+ return new_data
+
+ self.write_channel(self.RETURN)
+ main_delay = _increment_delay(main_delay)
+ time.sleep(main_delay)
+ i += 1
+
+ raise NetmikoTimeoutException("Timed out waiting for data")
+
+ def _build_ssh_client(self) -> paramiko.SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ remote_conn_pre = paramiko.SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def select_delay_factor(self, delay_factor: float) -> float:
+ """
+ Choose the greater of delay_factor or self.global_delay_factor (default).
+ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+ """
+ if self.fast_cli:
+ if delay_factor and delay_factor <= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+ else:
+ if delay_factor >= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
+ pass
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging default to a Cisco CLI method.
+
+ :param command: Device command to disable pagination of output
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
+ log.debug("Exiting disable_paging")
+ return output
+
+ def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """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
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if not command:
+ return ""
+ command = self.normalize_cmd(command)
+ self.write_channel(command)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
+ return output
+
+ # 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),
+ reraise=True,
+ )
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Cisco
+ devices this will be set to router hostname (i.e. prompt without > or #).
+
+ This will be set on entering user exec or privileged exec on Cisco, but not when
+ entering/exiting config mode.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
+ """
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
+ if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
+ # Strip off trailing terminator
+ self.base_prompt = prompt[:-1]
+ return self.base_prompt
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ """Finds the current network device prompt, last line only.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
+ self.clear_buffer()
+ self.write_channel(self.RETURN)
+
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
+
+ # If multiple lines in the output take the last line
+ prompt = prompt.split(self.RESPONSE_RETURN)[-1]
+ prompt = prompt.strip()
+ self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
+ return prompt
+
+ def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """Read any data available in the channel."""
+
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+ def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+ @select_cmd_verify
+ def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a delay-based mechanism. Generally
+ used for show commands.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
+ """
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+ self.write_channel(command_string)
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+ def _send_command_timing_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command_timing` method that always returns a
+ string"""
+ output = self.send_command_timing(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ :param a_string: Returned string from device
+ :type a_string: str
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ if self.base_prompt in last_line:
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def _first_line_handler(self, data: str, search_pattern: str) -> Tuple[str, bool]:
+ """
+ In certain situations the first line will get repainted which causes a false
+ match on the terminating pattern.
+
+ Filter this out.
+
+ returns a tuple of (data, first_line_processed)
+
+ Where data is the original data potentially with the first line modified
+ and the first_line_processed is a flag indicating that we have handled the
+ first line.
+ """
+ try:
+ # First line is the echo line containing the command. In certain situations
+ # it gets repainted and needs filtered
+ lines = data.split(self.RETURN)
+ first_line = lines[0]
+ if BACKSPACE_CHAR in first_line:
+ pattern = search_pattern + r".*$"
+ first_line = re.sub(pattern, repl="", string=first_line)
+ lines[0] = first_line
+ data = self.RETURN.join(lines)
+ return (data, True)
+ except IndexError:
+ return (data, False)
+
+ def _prompt_handler(self, auto_find_prompt: bool) -> str:
+ if auto_find_prompt:
+ try:
+ prompt = self.find_prompt()
+ except ValueError:
+ prompt = self.base_prompt
+ else:
+ prompt = self.base_prompt
+ return re.escape(prompt.strip())
+
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+ used for show commands. By default this method will keep waiting to receive data until the
+ network device prompt is detected. The current network device prompt will be determined
+ automatically.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param expect_string: Regular expression pattern to use for determining end of output.
+ If left blank will default to being based on router prompt.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
+ """
+
+ # Time to delay in each read loop
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
+ else:
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
+ else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
+ search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
+
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+
+ # Start the clock
+ start_time = time.time()
+ self.write_channel(command_string)
+ new_data = ""
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
+ if new_data:
+ output += new_data
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
+ if re.search(search_pattern, output):
+ break
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+ def _send_command_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command` method that always returns a string"""
+ output = self.send_command(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def send_command_expect(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+ def _multiline_kwargs(self, **kwargs: Any) -> Dict[str, Any]:
+ strip_prompt = kwargs.get("strip_prompt", False)
+ kwargs["strip_prompt"] = strip_prompt
+ strip_command = kwargs.get("strip_command", False)
+ kwargs["strip_command"] = strip_command
+ return kwargs
+
+ def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """
+ commands should either be:
+
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
+
+ """
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+ def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+ ) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
+
+ @staticmethod
+ def strip_backspaces(output: str) -> str:
+ """Strip any backspace characters out of the output.
+
+ :param output: Output obtained from a remote network device.
+ :type output: str
+ """
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """
+ Strip command_string from output string
+
+ Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+
+ :param command_string: The command string sent to the device
+ :type command_string: str
+
+ :param output: The returned output as a result of the command string sent to the device
+ :type output: str
+ """
+ backspace_char = "\x08"
+
+ # Check for line wrap (remove backspaces)
+ if backspace_char in output:
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
+ output_lines = output.split(self.RESPONSE_RETURN)
+ new_output = output_lines[1:]
+ return self.RESPONSE_RETURN.join(new_output)
+ else:
+ # command_string isn't there; do nothing
+ return output
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
+
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+ """
+ newline = re.compile("(\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":
+ # Convert any remaining \r to \n
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
+
+ def normalize_cmd(self, command: str) -> str:
+ """Normalize CLI commands to have a single trailing newline.
+
+ :param command: Command that may require line feed to be normalized
+ :type command: str
+ """
+ command = command.rstrip()
+ command += self.RETURN
+ return command
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ """Check if in enable mode. Return boolean.
+
+ :param check_string: Identification of privilege mode from device
+ :type check_string: str
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode.
+
+ :param cmd: Device command to enter enable mode
+
+ :param pattern: pattern to search for indicating device is waiting for password
+
+ :param enable_pattern: pattern indicating you have entered enable mode
+
+ :param re_flags: Regular expression flags used in conjunction with pattern
+ """
+ output = ""
+ msg = (
+ "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:
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ """Exit enable mode.
+
+ :param exit_command: Command that exits the session from privileged mode
+ :type exit_command: str
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ output += self.read_until_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ :param check_string: Identification of configuration mode from the device
+ :type check_string: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ 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)
+ return check_string in output
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode.
+
+ :param config_command: Configuration command to send to the device
+ :type config_command: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
+ """
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ """Exit from configuration mode.
+
+ :param exit_config: Command to exit configuration mode
+ :type exit_config: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel from a file.
+
+ The file is processed line-by-line and each command is sent down the
+ SSH channel.
+
+ **kwargs are passed to send_config_set method.
+
+ :param config_file: Path to configuration file to be sent to the device
+
+ :param kwargs: params to be sent to send_config_set method
+ """
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel.
+
+ config_commands is an iterable containing all of the configuration commands.
+ The commands will be executed one after the other.
+
+ Automatically exits/enters configuration mode.
+
+ :param config_commands: Multiple configuration commands to be sent to the device
+
+ :param exit_config_mode: Determines whether or not to exit config mode after complete
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Determines whether or not to strip the prompt
+
+ :param strip_command: Determines whether or not to strip the command
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+
+ :param config_mode_command: The command to enter into config mode
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
+ """
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
+ if config_commands is None:
+ return ""
+ elif isinstance(config_commands, str):
+ config_commands = (config_commands,)
+
+ if not hasattr(config_commands, "__iter__"):
+ raise ValueError("Invalid argument passed into send_config_set")
+
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
+ # Send config commands
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
+ log.debug(f"{output}")
+ return output
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Remove any ANSI (VT100) ESC codes from the output
+
+ http://en.wikipedia.org/wiki/ANSI_escape_code
+
+ Note: this does not capture ALL possible ANSI Escape Codes only the ones
+ I have encountered
+
+ Current codes that are filtered:
+ ESC = '\x1b' or chr(27)
+ ESC = is the escape character [^ in hex ('\x1b')
+ ESC[24;27H Position cursor
+ ESC[?25h Show the cursor
+ ESC[E Next line (HP does ESC-E)
+ ESC[K Erase line from cursor to the end of line
+ ESC[2K Erase entire line
+ ESC[1;24r Enable scrolling from start to row end
+ ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
+ ESC[?7l Disable line wrapping
+ ESC[2J Code erase display
+ ESC[00;32m Color Green (30 to 37 are different colors)
+ ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
+
+ HP ProCurve and Cisco SG300 require this (possible others).
+
+ :param string_buffer: The string to be processed to remove ANSI escape codes
+ :type string_buffer: str
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
+
+ output = string_buffer
+ for ansi_esc_code in code_set:
+ output = re.sub(ansi_esc_code, "", output)
+
+ # CODE_NEXT_LINE must substitute with return
+ output = re.sub(code_next_line, self.RETURN, output)
+
+ # Aruba and ProCurve switches can use code_insert_line for <enter>
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new <enter>
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
+
+ return output
+
+ def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
+ pass
+
+ def paramiko_cleanup(self) -> None:
+ """Cleanup Paramiko to try to gracefully handle SSH session ending."""
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
+ del self.remote_conn_pre
+
+ def disconnect(self) -> None:
+ """Try to gracefully close the session."""
+ try:
+ self.cleanup()
+ if self.protocol == "ssh":
+ self.paramiko_cleanup()
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ self.remote_conn.close()
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
+ self.remote_conn.close()
+ except Exception:
+ # There have been race conditions observed on disconnect.
+ pass
+ finally:
+ self.remote_conn_pre = None
+ self.remote_conn = None
+ if self.session_log:
+ self.session_log.close()
+
+ def commit(self) -> str:
+ """Commit method for platforms that support this."""
+ raise AttributeError("Network device does not support 'commit()' method")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def run_ttp(
+ self,
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+ ) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
+Subclasses
+
+Static methods
+
+
+def strip_backspaces(output)
+
+-
+
Strip any backspace characters out of the output.
+:param output: Output obtained from a remote network device.
+:type output: str
+
+Source code
+@staticmethod
+def strip_backspaces(output: str) -> str:
+ """Strip any backspace characters out of the output.
+
+ :param output: Output obtained from a remote network device.
+ :type output: str
+ """
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
+
+
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+:param check_string: Identification of configuration mode from the device
+:type check_string: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ :param check_string: Identification of configuration mode from the device
+ :type check_string: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ 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)
+ return check_string in output
+
+
+
+def check_enable_mode(self, check_string='')
+
+-
+
Check if in enable mode. Return boolean.
+:param check_string: Identification of privilege mode from device
+:type check_string: str
+
+Source code
+def check_enable_mode(self, check_string: str = "") -> bool:
+ """Check if in enable mode. Return boolean.
+
+ :param check_string: Identification of privilege mode from device
+ :type check_string: str
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+
+
+def cleanup(self, command='')
+
+-
+
Logout of the session on the network device plus any additional cleanup.
+
+Source code
+def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
+ pass
+
+
+
+def clear_buffer(self, backoff=True, backoff_max=3.0, delay_factor=None)
+
+-
+
Read any data available in the channel.
+
+Source code
+def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """Read any data available in the channel."""
+
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+
+
+def command_echo_read(self, cmd, read_timeout)
+
+-
+
+
+Source code
+def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+
+
+def commit(self)
+
+-
+
Commit method for platforms that support this.
+
+Source code
+def commit(self) -> str:
+ """Commit method for platforms that support this."""
+ raise AttributeError("Network device does not support 'commit()' method")
+
+
+
+def config_mode(self, config_command='', pattern='', re_flags=0)
+
+-
+
Enter into config_mode.
+:param config_command: Configuration command to send to the device
+:type config_command: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+:param re_flags: Regular expression flags
+:type re_flags: RegexFlag
+
+Source code
+def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter into config_mode.
+
+ :param config_command: Configuration command to send to the device
+ :type config_command: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
+ """
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+
+
+def disable_paging(self, command='terminal length 0', delay_factor=None, cmd_verify=True, pattern=None)
+
+-
+
Disable paging default to a Cisco CLI method.
+:param command: Device command to disable pagination of output
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+) -> str:
+ """Disable paging default to a Cisco CLI method.
+
+ :param command: Device command to disable pagination of output
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
+ log.debug("Exiting disable_paging")
+ return output
+
+
+
+def disconnect(self)
+
+-
+
Try to gracefully close the session.
+
+Source code
+def disconnect(self) -> None:
+ """Try to gracefully close the session."""
+ try:
+ self.cleanup()
+ if self.protocol == "ssh":
+ self.paramiko_cleanup()
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ self.remote_conn.close()
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
+ self.remote_conn.close()
+ except Exception:
+ # There have been race conditions observed on disconnect.
+ pass
+ finally:
+ self.remote_conn_pre = None
+ self.remote_conn = None
+ if self.session_log:
+ self.session_log.close()
+
+
+
+def enable(self, cmd='', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
Enter enable mode.
+:param cmd: Device command to enter enable mode
+:param pattern: pattern to search for indicating device is waiting for password
+:param enable_pattern: pattern indicating you have entered enable mode
+:param re_flags: Regular expression flags used in conjunction with pattern
+
+Source code
+def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter enable mode.
+
+ :param cmd: Device command to enter enable mode
+
+ :param pattern: pattern to search for indicating device is waiting for password
+
+ :param enable_pattern: pattern indicating you have entered enable mode
+
+ :param re_flags: Regular expression flags used in conjunction with pattern
+ """
+ output = ""
+ msg = (
+ "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:
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ return output
+
+
+
+def establish_connection(self, width=511, height=1000)
+
+-
+
Establish SSH connection to the network device
+Timeout will generate a NetmikoTimeoutException
+Authentication failure will generate a NetmikoAuthenticationException
+:param width: Specified width of the VT100 terminal window (default: 511)
+:type width: int
+:param height: Specified height of the VT100 terminal window (default: 1000)
+:type height: int
+
+Source code
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
+ """Establish SSH connection to the network device
+
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
+
+ :param width: Specified width of the VT100 terminal window (default: 511)
+ :type width: int
+
+ :param height: Specified height of the VT100 terminal window (default: 1000)
+ :type height: int
+ """
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.telnet_login()
+ elif self.protocol == "serial":
+ self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.serial_login()
+ elif self.protocol == "ssh":
+ ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
+ self.remote_conn_pre = self._build_ssh_client()
+
+ # initiate SSH connection
+ try:
+ self.remote_conn_pre.connect(**ssh_connect_params)
+ except socket.error as conn_error:
+ self.paramiko_cleanup()
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
+ except paramiko.ssh_exception.AuthenticationException as auth_err:
+ self.paramiko_cleanup()
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ msg += self.RETURN + str(auth_err)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
+
+ if self.verbose:
+ print(f"SSH connection established to {self.host}:{self.port}")
+
+ # Use invoke_shell to establish an 'interactive session'
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
+
+ self.remote_conn.settimeout(self.blocking_timeout)
+ if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
+ self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
+ self.special_login_handler()
+ if self.verbose:
+ print("Interactive SSH session established")
+
+ return None
+
+
+
+def exit_config_mode(self, exit_config='', pattern='')
+
+-
+
Exit from configuration mode.
+:param exit_config: Command to exit configuration mode
+:type exit_config: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+
+Source code
+def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ """Exit from configuration mode.
+
+ :param exit_config: Command to exit configuration mode
+ :type exit_config: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+
+
+def exit_enable_mode(self, exit_command='')
+
+-
+
Exit enable mode.
+:param exit_command: Command that exits the session from privileged mode
+:type exit_command: str
+
+Source code
+def exit_enable_mode(self, exit_command: str = "") -> str:
+ """Exit enable mode.
+
+ :param exit_command: Command that exits the session from privileged mode
+ :type exit_command: str
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ output += self.read_until_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+
+
+def find_prompt(self, delay_factor=1.0, pattern=None)
+
+-
+
Finds the current network device prompt, last line only.
+:param delay_factor: See init: global_delay_factor
+:type delay_factor: int
+:param pattern: Regular expression pattern to determine whether prompt is valid
+
+Source code
+def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+) -> str:
+ """Finds the current network device prompt, last line only.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
+ self.clear_buffer()
+ self.write_channel(self.RETURN)
+
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
+
+ # If multiple lines in the output take the last line
+ prompt = prompt.split(self.RESPONSE_RETURN)[-1]
+ prompt = prompt.strip()
+ self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
+ return prompt
+
+
+
+def is_alive(self)
+
+-
+
Returns a boolean flag with the state of the connection.
+
+Source code
+def is_alive(self) -> bool:
+ """Returns a boolean flag with the state of the connection."""
+ null = chr(0)
+ if self.remote_conn is None:
+ log.error("Connection is not initialised, is_alive returns False")
+ return False
+ if self.protocol == "telnet":
+ try:
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
+ log.debug("Sending IAC + NOP")
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
+ except AttributeError:
+ return False
+ else:
+ # SSH
+ try:
+ # Try sending ASCII null byte to maintain the connection alive
+ log.debug("Sending the NULL byte")
+ self.write_channel(null)
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
+ except (socket.error, EOFError):
+ log.error("Unable to send", exc_info=True)
+ # If unable to send, we can tell for sure that the connection is unusable
+ return False
+ return False
+
+
+
+def normalize_cmd(self, command)
+
+-
+
Normalize CLI commands to have a single trailing newline.
+:param command: Command that may require line feed to be normalized
+:type command: str
+
+Source code
+def normalize_cmd(self, command: str) -> str:
+ """Normalize CLI commands to have a single trailing newline.
+
+ :param command: Command that may require line feed to be normalized
+ :type command: str
+ """
+ command = command.rstrip()
+ command += self.RETURN
+ return command
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Convert `
+,
+,
+to
+.`
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
+
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+ """
+ newline = re.compile("(\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":
+ # Convert any remaining \r to \n
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
+
+
+
+def paramiko_cleanup(self)
+
+-
+
Cleanup Paramiko to try to gracefully handle SSH session ending.
+
+Source code
+def paramiko_cleanup(self) -> None:
+ """Cleanup Paramiko to try to gracefully handle SSH session ending."""
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
+ del self.remote_conn_pre
+
+
+
+def read_channel(self)
+
+-
+
Generic handler that will read all the data from given channel.
+
+Source code
+@lock_channel
+def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
+ return output
+
+
+
+def read_channel_timing(self, last_read=2.0, read_timeout=120.0, delay_factor=None, max_loops=None)
+
+-
+
Read data on the channel based on timing delays.
+General pattern is keep reading until no new data is read.
+Once no new data is read wait last_read amount of time (one last read).
+As long as no new data, then return data.
+read_timeout is an absolute timer for how long to keep reading (which presupposes
+we are still getting new data).
+Setting read_timeout to zero will cause read_channel_timing to never expire based
+on an absolute timeout. It will only complete based on timeout based on their being
+no new data.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read data on the channel based on timing delays.
+
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
+
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
+
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
+ channel_data = ""
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+ # gather new output
+ if new_data:
+ channel_data += new_data
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
+ new_data = self.read_channel()
+ if not new_data:
+ break
+ else:
+ channel_data += new_data
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
+
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
+
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
+
+You can look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+ return channel_data
+
+
+
+def read_until_pattern(self, pattern='', read_timeout=10.0, re_flags=0, max_loops=None)
+
+-
+
Read channel until pattern is detected.
+Will return string up to and including pattern.
+Returns ReadTimeout if pattern not detected in read_timeout seconds.
+:param pattern: Regular expression pattern used to identify that reading is done.
+:param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+reading indefinitely until pattern is detected.
+:param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
+
+ Will return string up to and including pattern.
+
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
+
+ :param pattern: Regular expression pattern used to identify that reading is done.
+
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
+
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
+ return output
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
+
+
+
+def read_until_prompt(self, read_timeout=10.0, read_entire_line=False, re_flags=0, max_loops=None)
+
+-
+
Read channel up to and including self.base_prompt.
+
+Source code
+def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+
+
+def read_until_prompt_or_pattern(self, pattern='', read_timeout=10.0, read_entire_line=False, re_flags=0, max_loops=None)
+
+-
+
Read until either self.base_prompt or pattern is detected.
+
+Source code
+def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
+ if pattern:
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+
+
+def run_ttp(self, template, res_kwargs=None, **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
+:param res_kwargs: **res_kwargs arguments to pass to TTP result method
+:param kwargs: any other **kwargs to use for TTP object instantiation
+TTP template must have inputs defined together with below parameters.
+:param method: name of Netmiko connection object method to call, default send_command
+:param kwargs: Netmiko connection object method arguments
+:param commands: list of commands to collect
+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: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def select_delay_factor(self, delay_factor)
+
+-
+
Choose the greater of delay_factor or self.global_delay_factor (default).
+In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+:param delay_factor: See init: global_delay_factor
+:type delay_factor: int
+
+Source code
+def select_delay_factor(self, delay_factor: float) -> float:
+ """
+ Choose the greater of delay_factor or self.global_delay_factor (default).
+ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+ """
+ if self.fast_cli:
+ if delay_factor and delay_factor <= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+ else:
+ if delay_factor >= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+
+
+
+def send_command(self, command_string, expect_string=None, read_timeout=10.0, delay_factor=None, max_loops=None, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=True)
+
+-
+
Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+used for show commands. By default this method will keep waiting to receive data until the
+network device prompt is detected. The current network device prompt will be determined
+automatically.
+:param command_string: The command to be executed on the remote device.
+:param expect_string: Regular expression pattern to use for determining end of output.
+If left blank will default to being based on router prompt.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Remove the trailing router prompt from the output (default: True).
+:param strip_command: Remove the echo of the command from the output (default: True).
+:param normalize: Ensure the proper enter is sent at end of command (default: True).
+:param use_textfsm: Process command output through TextFSM template (default: False).
+:param textfsm_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_ttp: Process command output through TTP template (default: False).
+:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_genie: Process command output through PyATS/Genie parser (default: False).
+:param cmd_verify: Verify command echo before proceeding (default: True).
+
+Source code
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+ used for show commands. By default this method will keep waiting to receive data until the
+ network device prompt is detected. The current network device prompt will be determined
+ automatically.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param expect_string: Regular expression pattern to use for determining end of output.
+ If left blank will default to being based on router prompt.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
+ """
+
+ # Time to delay in each read loop
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
+ else:
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
+ else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
+ search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
+
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+
+ # Start the clock
+ start_time = time.time()
+ self.write_channel(command_string)
+ new_data = ""
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
+ if new_data:
+ output += new_data
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
+ if re.search(search_pattern, output):
+ break
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+
+
+def send_command_expect(self, *args, **kwargs)
+
+-
+
Support previous name of send_command method.
+
+Source code
+def send_command_expect(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+
+
+def send_command_timing(self, command_string, last_read=2.0, read_timeout=120.0, delay_factor=None, max_loops=None, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=False)
+
+-
+
Execute command_string on the SSH channel using a delay-based mechanism. Generally
+used for show commands.
+:param command_string: The command to be executed on the remote device.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Remove the trailing router prompt from the output (default: True).
+:param strip_command: Remove the echo of the command from the output (default: True).
+:param normalize: Ensure the proper enter is sent at end of command (default: True).
+:param use_textfsm: Process command output through TextFSM template (default: False).
+:param textfsm_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_ttp: Process command output through TTP template (default: False).
+:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_genie: Process command output through PyATS/Genie parser (default: False).
+:param cmd_verify: Verify command echo before proceeding (default: False).
+
+Source code
+@select_cmd_verify
+def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a delay-based mechanism. Generally
+ used for show commands.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
+ """
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+ self.write_channel(command_string)
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+
+
+def send_config_from_file(self, config_file, **kwargs)
+
+-
+
Send configuration commands down the SSH channel from a file.
+The file is processed line-by-line and each command is sent down the
+SSH channel.
+**kwargs are passed to send_config_set method.
+:param config_file: Path to configuration file to be sent to the device
+:param kwargs: params to be sent to send_config_set method
+
+Source code
+def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+) -> str:
+ """
+ Send configuration commands down the SSH channel from a file.
+
+ The file is processed line-by-line and each command is sent down the
+ SSH channel.
+
+ **kwargs are passed to send_config_set method.
+
+ :param config_file: Path to configuration file to be sent to the device
+
+ :param kwargs: params to be sent to send_config_set method
+ """
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+
+
+def send_config_set(self, config_commands=None, *, exit_config_mode=True, read_timeout=None, delay_factor=None, max_loops=None, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True, error_pattern='', terminator='#', bypass_commands=None)
+
+-
+
Send configuration commands down the SSH channel.
+config_commands is an iterable containing all of the configuration commands.
+The commands will be executed one after the other.
+Automatically exits/enters configuration mode.
+:param config_commands: Multiple configuration commands to be sent to the device
+:param exit_config_mode: Determines whether or not to exit config mode after complete
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Determines whether or not to strip the prompt
+:param strip_command: Determines whether or not to strip the command
+:param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+:param config_mode_command: The command to enter into config mode
+:param cmd_verify: Whether or not to verify command echo for each command in config_set
+:param enter_config_mode: Do you enter config mode before sending config commands
+:param error_pattern: Regular expression pattern to detect config errors in the
+output.
+:param terminator: Regular expression pattern to use as an alternate terminator in certain
+situations.
+:param bypass_commands: Regular expression pattern indicating configuration commands
+where cmd_verify is automatically disabled.
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+) -> str:
+ """
+ Send configuration commands down the SSH channel.
+
+ config_commands is an iterable containing all of the configuration commands.
+ The commands will be executed one after the other.
+
+ Automatically exits/enters configuration mode.
+
+ :param config_commands: Multiple configuration commands to be sent to the device
+
+ :param exit_config_mode: Determines whether or not to exit config mode after complete
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Determines whether or not to strip the prompt
+
+ :param strip_command: Determines whether or not to strip the command
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+
+ :param config_mode_command: The command to enter into config mode
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
+ """
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
+ if config_commands is None:
+ return ""
+ elif isinstance(config_commands, str):
+ config_commands = (config_commands,)
+
+ if not hasattr(config_commands, "__iter__"):
+ raise ValueError("Invalid argument passed into send_config_set")
+
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
+ # Send config commands
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
+ log.debug(f"{output}")
+ return output
+
+
+
+def send_multiline(self, commands, multiline=True, **kwargs)
+
+-
+
commands should either be:
+commands = [[cmd1, expect1], [cmd2, expect2], …]]
+Or
+commands = [cmd1, cmd2, cmd3, …]
+Any expect_string that is a null-string will use pattern based on
+device's prompt (unless expect_string argument is passed in via
+kwargs.
+
+Source code
+def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+) -> str:
+ """
+ commands should either be:
+
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
+
+ """
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+
+
+def send_multiline_timing(self, commands, multiline=True, **kwargs)
+
+-
+
+
+Source code
+def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
+
+
+
+def serial_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:[Uu]ser:|sername|ogin)', pwd_pattern='assword', delay_factor=1.0, max_loops=20)
+
+-
+
+
+Source code
+def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+This method handles some differences that occur between various devices
+early on in the session.
+In general, it should include:
+self._test_channel_read(pattern=r"some_pattern")
+self.set_base_prompt()
+self.set_terminal_width()
+self.disable_paging()
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some differences that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self._test_channel_read(pattern=r"some_pattern")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='#', alt_prompt_terminator='>', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt
+Used as delimiter for stripping of trailing prompt in output.
+Should be set to something that is general and applies in multiple contexts. For Cisco
+devices this will be set to router hostname (i.e. prompt without > or #).
+This will be set on entering user exec or privileged exec on Cisco, but not when
+entering/exiting config mode.
+:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+:param delay_factor: See init: global_delay_factor
+:param pattern: Regular expression pattern to search for in find_prompt() call
+
+Source code
+@retry(
+ 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: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Cisco
+ devices this will be set to router hostname (i.e. prompt without > or #).
+
+ This will be set on entering user exec or privileged exec on Cisco, but not when
+ entering/exiting config mode.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
+ """
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
+ if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
+ # Strip off trailing terminator
+ self.base_prompt = prompt[:-1]
+ return self.base_prompt
+
+
+
+def set_terminal_width(self, command='', delay_factor=None, cmd_verify=False, pattern=None)
+
+-
+
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
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+) -> str:
+ """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
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if not command:
+ return ""
+ command = self.normalize_cmd(command)
+ self.write_channel(command)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
+ return output
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Handler for devices like WLC, Extreme ERS that throw up characters prior to login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
+ pass
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
Remove any ANSI (VT100) ESC codes from the output
+http://en.wikipedia.org/wiki/ANSI_escape_code
+Note: this does not capture ALL possible ANSI Escape Codes only the ones
+I have encountered
+Current codes that are filtered:
+ESC = '' or chr(27)
+ESC = is the escape character [^ in hex ('')
+ESC[24;27H
+Position cursor
+ESC[?25h
+Show the cursor
+ESC[E
+Next line (HP does ESC-E)
+ESC[K
+Erase line from cursor to the end of line
+ESC[2K
+Erase entire line
+ESC[1;24r
+Enable scrolling from start to row end
+ESC[?6l
+Reset mode screen with options 640 x 200 monochrome (graphics)
+ESC[?7l
+Disable line wrapping
+ESC[2J
+Code erase display
+ESC[00;32m
+Color Green (30 to 37 are different colors)
+ESC[6n
+Get cursor position
+ESC[1D
+Move cursor position leftward by x characters (1 in this case)
+ESC[9999B
+Move cursor down N-lines (very large value is attempt to move to the
+very bottom of the screen).
+HP ProCurve and Cisco SG300 require this (possible others).
+:param string_buffer: The string to be processed to remove ANSI escape codes
+:type string_buffer: str
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Remove any ANSI (VT100) ESC codes from the output
+
+ http://en.wikipedia.org/wiki/ANSI_escape_code
+
+ Note: this does not capture ALL possible ANSI Escape Codes only the ones
+ I have encountered
+
+ Current codes that are filtered:
+ ESC = '\x1b' or chr(27)
+ ESC = is the escape character [^ in hex ('\x1b')
+ ESC[24;27H Position cursor
+ ESC[?25h Show the cursor
+ ESC[E Next line (HP does ESC-E)
+ ESC[K Erase line from cursor to the end of line
+ ESC[2K Erase entire line
+ ESC[1;24r Enable scrolling from start to row end
+ ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
+ ESC[?7l Disable line wrapping
+ ESC[2J Code erase display
+ ESC[00;32m Color Green (30 to 37 are different colors)
+ ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
+
+ HP ProCurve and Cisco SG300 require this (possible others).
+
+ :param string_buffer: The string to be processed to remove ANSI escape codes
+ :type string_buffer: str
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
+
+ output = string_buffer
+ for ansi_esc_code in code_set:
+ output = re.sub(ansi_esc_code, "", output)
+
+ # CODE_NEXT_LINE must substitute with return
+ output = re.sub(code_next_line, self.RETURN, output)
+
+ # Aruba and ProCurve switches can use code_insert_line for <enter>
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new <enter>
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
+
+ return output
+
+
+
+def strip_command(self, command_string, output)
+
+-
+
Strip command_string from output string
+Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+:param command_string: The command string sent to the device
+:type command_string: str
+:param output: The returned output as a result of the command string sent to the device
+:type output: str
+
+Source code
+def strip_command(self, command_string: str, output: str) -> str:
+ """
+ Strip command_string from output string
+
+ Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+
+ :param command_string: The command string sent to the device
+ :type command_string: str
+
+ :param output: The returned output as a result of the command string sent to the device
+ :type output: str
+ """
+ backspace_char = "\x08"
+
+ # Check for line wrap (remove backspaces)
+ if backspace_char in output:
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
+ output_lines = output.split(self.RESPONSE_RETURN)
+ new_output = output_lines[1:]
+ return self.RESPONSE_RETURN.join(new_output)
+ else:
+ # command_string isn't there; do nothing
+ return output
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+:param a_string: Returned string from device
+:type a_string: str
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ :param a_string: Returned string from device
+ :type a_string: str
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ if self.base_prompt in last_line:
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+
+
+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.0, max_loops=20)
+
+-
+
Telnet login. Can be username/password or just password.
+:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+:param username_pattern: Pattern used to identify the username prompt
+:param delay_factor: See init: global_delay_factor
+:param max_loops: Controls the wait time in conjunction with the delay_factor
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """Telnet login. Can be username/password or just password.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param username_pattern: Pattern used to identify the username prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param max_loops: Controls the wait time in conjunction with the delay_factor
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+
+
+def write_channel(self, out_data)
+
+-
+
Generic method that will write data out the channel.
+:param out_data: data to be written to the channel
+:type out_data: str
+
+Source code
+@lock_channel
+@log_writes
+def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
+
+ :param out_data: data to be written to the channel
+ :type out_data: str
+ """
+ self.channel.write_channel(out_data)
+
+
+
+
+
+class SecretsFilter
+(no_log=None)
+
+-
+
Filter instances are used to perform arbitrary filtering of LogRecords.
+Loggers and Handlers can optionally use Filter instances to filter
+records as desired. The base filter class only allows events which are
+below a certain point in the logger hierarchy. For example, a filter
+initialized with "A.B" will allow events logged by loggers "A.B",
+"A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
+initialized with the empty string, all events are passed.
+Initialize a filter.
+Initialize with the name of the logger which, together with its
+children, will have its events allowed through the filter. If no
+name is specified, allow every event.
+
+Source code
+class SecretsFilter(logging.Filter):
+ def __init__(self, no_log: Optional[Dict[Any, str]] = None) -> None:
+ self.no_log = no_log
+
+ def filter(self, record: logging.LogRecord) -> bool:
+ """Removes secrets (no_log) from messages"""
+ if self.no_log:
+ for hidden_data in self.no_log.values():
+ record.msg = record.msg.replace(hidden_data, "********")
+ return True
+
+Ancestors
+
+Methods
+
+
+def filter(self, record)
+
+-
+
Removes secrets (no_log) from messages
+
+Source code
+def filter(self, record: logging.LogRecord) -> bool:
+ """Removes secrets (no_log) from messages"""
+ if self.no_log:
+ for hidden_data in self.no_log.values():
+ record.msg = record.msg.replace(hidden_data, "********")
+ return True
+
+
+
+
+
+class TelnetConnection
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TelnetConnection(BaseConnection):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/broadcom/broadcom_icos_ssh.html b/docs/netmiko/broadcom/broadcom_icos_ssh.html
new file mode 100644
index 000000000..381e7153d
--- /dev/null
+++ b/docs/netmiko/broadcom/broadcom_icos_ssh.html
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+netmiko.broadcom.broadcom_icos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.broadcom.broadcom_icos_ssh
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class BroadcomIcosSSH(CiscoSSHConnection):
+ """
+ Implements support for Broadcom Icos devices.
+ Syntax its almost identical to Cisco IOS in most cases
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class BroadcomIcosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Broadcom Icos devices.
+Syntax its almost identical to Cisco IOS in most cases
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class BroadcomIcosSSH(CiscoSSHConnection):
+ """
+ Implements support for Broadcom Icos devices.
+ Syntax its almost identical to Cisco IOS in most cases
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+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: str = ")#", pattern: str = "") -> bool:
+ """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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/broadcom/index.html b/docs/netmiko/broadcom/index.html
new file mode 100644
index 000000000..f5a71b448
--- /dev/null
+++ b/docs/netmiko/broadcom/index.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+netmiko.broadcom API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.broadcom
+
+
+
+Source code
+from netmiko.broadcom.broadcom_icos_ssh import BroadcomIcosSSH
+
+
+__all__ = ["BroadcomIcosSSH"]
+
+
+
+
+
+
+
+
+
+class BroadcomIcosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Broadcom Icos devices.
+Syntax its almost identical to Cisco IOS in most cases
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class BroadcomIcosSSH(CiscoSSHConnection):
+ """
+ Implements support for Broadcom Icos devices.
+ Syntax its almost identical to Cisco IOS in most cases
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+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: str = ")#", pattern: str = "") -> bool:
+ """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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/brocade/brocade_fos_ssh.html b/docs/netmiko/brocade/brocade_fos_ssh.html
new file mode 100644
index 000000000..74842c86d
--- /dev/null
+++ b/docs/netmiko/brocade/brocade_fos_ssh.html
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+netmiko.brocade.brocade_fos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.brocade.brocade_fos_ssh
+
+
+
+Source code
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class BrocadeFOSSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Brocade Fabric OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+
+
+
+
+
+
+
+
+
+class BrocadeFOSSSH
+(**kwargs)
+
+-
+
Brocade Fabric OS support
+
+Source code
+class BrocadeFOSSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Brocade Fabric OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+
+Ancestors
+
+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..2fddb4882
--- /dev/null
+++ b/docs/netmiko/brocade/index.html
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+netmiko.brocade API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.brocade
+
+
+
+Source code
+from netmiko.brocade.brocade_fos_ssh import BrocadeFOSSSH
+
+__all__ = ["BrocadeFOSSSH"]
+
+
+
+
+
+
+
+
+
+class BrocadeFOSSSH
+(**kwargs)
+
+-
+
Brocade Fabric OS support
+
+Source code
+class BrocadeFOSSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Brocade Fabric OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/calix/calix_b6.html b/docs/netmiko/calix/calix_b6.html
new file mode 100644
index 000000000..0f2cf600e
--- /dev/null
+++ b/docs/netmiko/calix/calix_b6.html
@@ -0,0 +1,866 @@
+
+
+
+
+
+
+netmiko.calix.calix_b6 API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.calix.calix_b6
+
+
+Calix B6 SSH Driver for Netmiko
+
+Source code
+"""Calix B6 SSH Driver for Netmiko"""
+from typing import Any
+import time
+from os import path
+
+from paramiko import SSHClient
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.exceptions import NetmikoTimeoutException
+
+
+class CalixB6Base(CiscoSSHConnection):
+ """Common methods for Calix B6, both SSH and Telnet."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> Any:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Calix B6 presents with the following on login:
+
+ login as:
+ Password: ****
+ """
+ new_data = ""
+ time.sleep(0.1)
+ start = time.time()
+ login_timeout = 20
+ while time.time() - start < login_timeout:
+ output = self.read_channel() if not new_data else new_data
+ new_data = ""
+ if output:
+ if "login as:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.1)
+ else:
+ # No new data...sleep longer
+ time.sleep(0.5)
+ new_data = self.read_channel()
+ # If still no data, send an <enter>
+ if not new_data:
+ self.write_channel(self.RETURN)
+ else: # no-break
+ msg = """
+Login process failed to Calix B6 device. Unable to login in {login_timeout} seconds.
+"""
+ raise NetmikoTimeoutException(msg)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string)
+
+ def save_config(
+ self,
+ cmd: str = "copy run start",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CalixB6SSH(CalixB6Base):
+ """Calix B6 SSH Driver.
+
+ To make it work, we have to override the SSHClient _auth method and manually handle
+ the username/password.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+
+class CalixB6Telnet(CalixB6Base):
+ """Calix B6 Telnet Driver."""
+
+ pass
+
+
+
+
+
+
+
+
+
+class CalixB6Base
+(*args, **kwargs)
+
+-
+
Common methods for Calix B6, both SSH and Telnet.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CalixB6Base(CiscoSSHConnection):
+ """Common methods for Calix B6, both SSH and Telnet."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> Any:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Calix B6 presents with the following on login:
+
+ login as:
+ Password: ****
+ """
+ new_data = ""
+ time.sleep(0.1)
+ start = time.time()
+ login_timeout = 20
+ while time.time() - start < login_timeout:
+ output = self.read_channel() if not new_data else new_data
+ new_data = ""
+ if output:
+ if "login as:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.1)
+ else:
+ # No new data...sleep longer
+ time.sleep(0.5)
+ new_data = self.read_channel()
+ # If still no data, send an <enter>
+ if not new_data:
+ self.write_channel(self.RETURN)
+ else: # no-break
+ msg = """
+Login process failed to Calix B6 device. Unable to login in {login_timeout} seconds.
+"""
+ raise NetmikoTimeoutException(msg)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string)
+
+ def save_config(
+ self,
+ cmd: str = "copy run start",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=')#', pattern='')
+
+-
+
Checks if the device is in configuration mode
+
+Source code
+def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> Any:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging()
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Calix B6 presents with the following on login:
+login as:
+Password: ****
+
+Source code
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Calix B6 presents with the following on login:
+
+ login as:
+ Password: ****
+ """
+ new_data = ""
+ time.sleep(0.1)
+ start = time.time()
+ login_timeout = 20
+ while time.time() - start < login_timeout:
+ output = self.read_channel() if not new_data else new_data
+ new_data = ""
+ if output:
+ if "login as:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.1)
+ else:
+ # No new data...sleep longer
+ time.sleep(0.5)
+ new_data = self.read_channel()
+ # If still no data, send an <enter>
+ if not new_data:
+ self.write_channel(self.RETURN)
+ else: # no-break
+ msg = """
+Login process failed to Calix B6 device. Unable to login in {login_timeout} seconds.
+"""
+ raise NetmikoTimeoutException(msg)
+
+
+
+Inherited members
+
+
+
+class CalixB6SSH
+(*args, **kwargs)
+
+-
+
Calix B6 SSH Driver.
+To make it work, we have to override the SSHClient _auth method and manually handle
+the username/password.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CalixB6SSH(CalixB6Base):
+ """Calix B6 SSH Driver.
+
+ To make it work, we have to override the SSHClient _auth method and manually handle
+ the username/password.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class CalixB6Telnet
+(*args, **kwargs)
+
+-
+
Calix B6 Telnet Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CalixB6Telnet(CalixB6Base):
+ """Calix B6 Telnet Driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/calix/index.html b/docs/netmiko/calix/index.html
new file mode 100644
index 000000000..254b35f05
--- /dev/null
+++ b/docs/netmiko/calix/index.html
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+netmiko.calix API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.calix.calix_b6 import CalixB6SSH, CalixB6Telnet
+
+__all__ = ["CalixB6SSH", "CalixB6Telnet"]
+
+
+
+
+
+
+
+
+
+class CalixB6SSH
+(*args, **kwargs)
+
+-
+
Calix B6 SSH Driver.
+To make it work, we have to override the SSHClient _auth method and manually handle
+the username/password.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CalixB6SSH(CalixB6Base):
+ """Calix B6 SSH Driver.
+
+ To make it work, we have to override the SSHClient _auth method and manually handle
+ the username/password.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class CalixB6Telnet
+(*args, **kwargs)
+
+-
+
Calix B6 Telnet Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CalixB6Telnet(CalixB6Base):
+ """Calix B6 Telnet Driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cdot/cdot_cros_ssh.html b/docs/netmiko/cdot/cdot_cros_ssh.html
new file mode 100644
index 000000000..b476d4ebf
--- /dev/null
+++ b/docs/netmiko/cdot/cdot_cros_ssh.html
@@ -0,0 +1,579 @@
+
+
+
+
+
+
+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>
+# Updated by Kirk Byers
+#
+# Purpose: Provide basic SSH connection to CROS based router products
+
+from typing import Optional, Union, Sequence, TextIO, Any
+import time
+import warnings
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class CdotCrosSSH(NoEnable, CiscoBaseConnection):
+ """Implement methods for interacting with CROS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ return
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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 _disable_complete_on_space(self) -> str:
+ """
+ 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
+
+
+
+
+
+
+
+
+
+class CdotCrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CdotCrosSSH(NoEnable, CiscoBaseConnection):
+ """Implement methods for interacting with CROS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ return
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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 _disable_complete_on_space(self) -> str:
+ """
+ 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: str = ")#", pattern: str = r"[#\$]"
+) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None, 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+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: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ 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..3237ca26a
--- /dev/null
+++ b/docs/netmiko/cdot/index.html
@@ -0,0 +1,479 @@
+
+
+
+
+
+
+netmiko.cdot API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.cdot.cdot_cros_ssh import CdotCrosSSH
+
+__all__ = ["CdotCrosSSH"]
+
+
+
+
+
+
+
+
+
+class CdotCrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CdotCrosSSH(NoEnable, CiscoBaseConnection):
+ """Implement methods for interacting with CROS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ return
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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 _disable_complete_on_space(self) -> str:
+ """
+ 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: str = ")#", pattern: str = r"[#\$]"
+) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None, 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+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: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ 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
new file mode 100644
index 000000000..2c7233d15
--- /dev/null
+++ b/docs/netmiko/centec/centec_os.html
@@ -0,0 +1,661 @@
+
+
+
+
+
+
+netmiko.centec.centec_os API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.centec.centec_os
+
+
+Centec OS Support
+
+Source code
+"""Centec OS Support"""
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class CentecOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CentecOSSSH(CentecOSBase):
+
+ pass
+
+
+class CentecOSTelnet(CentecOSBase):
+
+ pass
+
+
+
+
+
+
+
+
+
+class CentecOSBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CentecOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Save config: write"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+
+
+Inherited members
+
+
+
+class CentecOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CentecOSSSH(CentecOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CentecOSTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CentecOSTelnet(CentecOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/centec/index.html b/docs/netmiko/centec/index.html
new file mode 100644
index 000000000..ae0adcdc8
--- /dev/null
+++ b/docs/netmiko/centec/index.html
@@ -0,0 +1,424 @@
+
+
+
+
+
+
+netmiko.centec API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.centec.centec_os import CentecOSSSH, CentecOSTelnet
+
+__all__ = ["CentecOSSSH", "CentecOSTelnet"]
+
+
+
+
+
+
+
+
+
+class CentecOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CentecOSSSH(CentecOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CentecOSTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CentecOSTelnet(CentecOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/channel.html b/docs/netmiko/channel.html
new file mode 100644
index 000000000..4ca1f8906
--- /dev/null
+++ b/docs/netmiko/channel.html
@@ -0,0 +1,540 @@
+
+
+
+
+
+
+netmiko.channel API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.channel
+
+
+
+Source code
+from typing import Any, Optional
+from abc import ABC, abstractmethod
+import paramiko
+import telnetlib
+import serial
+
+from netmiko.utilities import write_bytes
+from netmiko.netmiko_globals import MAX_BUFFER
+from netmiko.exceptions import ReadException, WriteException
+
+
+class Channel(ABC):
+ @abstractmethod
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Create the object."""
+ pass
+
+ # @abstractmethod
+ # def __repr__(self) -> str:
+ # """String representation of the object."""
+ # pass
+ #
+ # @abstractmethod
+ # def open(self, width: int = 511, height: int = 1000) -> None:
+ # """Create the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def close(self) -> None:
+ # """Close the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def login(self) -> None:
+ # """Handle the channel login process for any channel that requires it."""
+ # pass
+
+ @abstractmethod
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ pass
+
+ @abstractmethod
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ pass
+
+ @abstractmethod
+ def write_channel(self, out_data: str) -> None:
+ """Write data down the channel."""
+ pass
+
+ # @abstractmethod
+ # def is_alive(self) -> bool:
+ # """Is the channel alive."""
+ # pass
+
+
+class SSHChannel(Channel):
+ def __init__(self, conn: Optional[paramiko.Channel], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.sendall(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ if self.remote_conn.recv_ready():
+ outbuf = self.remote_conn.recv(MAX_BUFFER)
+ if len(outbuf) == 0:
+ raise ReadException("Channel stream closed by remote device.")
+ output += outbuf.decode("utf-8", "ignore")
+ return output
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while True:
+ new_output = self.read_buffer()
+ output += new_output
+ if new_output == "":
+ break
+ return output
+
+
+class TelnetChannel(Channel):
+ def __init__(self, conn: Optional[telnetlib.Telnet], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ raise NotImplementedError
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ return self.remote_conn.read_very_eager().decode("utf-8", "ignore")
+
+
+class SerialChannel(Channel):
+ def __init__(self, conn: Optional[serial.Serial], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+ self.remote_conn.flush()
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ if self.remote_conn.in_waiting > 0:
+ output = self.remote_conn.read(self.remote_conn.in_waiting).decode(
+ "utf-8", "ignore"
+ )
+ assert isinstance(output, str)
+ return output
+ else:
+ return ""
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while self.remote_conn.in_waiting > 0:
+ output += self.read_buffer()
+ return output
+
+
+
+
+
+
+
+
+
+class Channel
+(*args, **kwargs)
+
+-
+
Helper class that provides a standard way to create an ABC using
+inheritance.
+Create the object.
+
+Source code
+class Channel(ABC):
+ @abstractmethod
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Create the object."""
+ pass
+
+ # @abstractmethod
+ # def __repr__(self) -> str:
+ # """String representation of the object."""
+ # pass
+ #
+ # @abstractmethod
+ # def open(self, width: int = 511, height: int = 1000) -> None:
+ # """Create the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def close(self) -> None:
+ # """Close the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def login(self) -> None:
+ # """Handle the channel login process for any channel that requires it."""
+ # pass
+
+ @abstractmethod
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ pass
+
+ @abstractmethod
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ pass
+
+ @abstractmethod
+ def write_channel(self, out_data: str) -> None:
+ """Write data down the channel."""
+ pass
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def read_buffer(self)
+
+-
+
Single read of available data.
+
+Source code
+@abstractmethod
+def read_buffer(self) -> str:
+ """Single read of available data."""
+ pass
+
+
+
+def read_channel(self)
+
+-
+
Read all of the available data from the channel.
+
+Source code
+@abstractmethod
+def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ pass
+
+
+
+def write_channel(self, out_data)
+
+-
+
Write data down the channel.
+
+Source code
+@abstractmethod
+def write_channel(self, out_data: str) -> None:
+ """Write data down the channel."""
+ pass
+
+
+
+
+
+class SSHChannel
+(conn, encoding)
+
+-
+
Helper class that provides a standard way to create an ABC using
+inheritance.
+Placeholder init method so that reading and writing can be moved to the
+channel class.
+
+Source code
+class SSHChannel(Channel):
+ def __init__(self, conn: Optional[paramiko.Channel], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.sendall(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ if self.remote_conn.recv_ready():
+ outbuf = self.remote_conn.recv(MAX_BUFFER)
+ if len(outbuf) == 0:
+ raise ReadException("Channel stream closed by remote device.")
+ output += outbuf.decode("utf-8", "ignore")
+ return output
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while True:
+ new_output = self.read_buffer()
+ output += new_output
+ if new_output == "":
+ break
+ return output
+
+Ancestors
+
+Inherited members
+
+
+
+class SerialChannel
+(conn, encoding)
+
+-
+
Helper class that provides a standard way to create an ABC using
+inheritance.
+Placeholder init method so that reading and writing can be moved to the
+channel class.
+
+Source code
+class SerialChannel(Channel):
+ def __init__(self, conn: Optional[serial.Serial], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+ self.remote_conn.flush()
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ if self.remote_conn.in_waiting > 0:
+ output = self.remote_conn.read(self.remote_conn.in_waiting).decode(
+ "utf-8", "ignore"
+ )
+ assert isinstance(output, str)
+ return output
+ else:
+ return ""
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while self.remote_conn.in_waiting > 0:
+ output += self.read_buffer()
+ return output
+
+Ancestors
+
+Inherited members
+
+
+
+class TelnetChannel
+(conn, encoding)
+
+-
+
Helper class that provides a standard way to create an ABC using
+inheritance.
+Placeholder init method so that reading and writing can be moved to the
+channel class.
+
+Source code
+class TelnetChannel(Channel):
+ def __init__(self, conn: Optional[telnetlib.Telnet], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ raise NotImplementedError
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ return self.remote_conn.read_very_eager().decode("utf-8", "ignore")
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html b/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html
new file mode 100644
index 000000000..d414540aa
--- /dev/null
+++ b/docs/netmiko/checkpoint/checkpoint_gaia_ssh.html
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+netmiko.checkpoint.checkpoint_gaia_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.checkpoint.checkpoint_gaia_ssh
+
+
+
+Source code
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class CheckPointGaiaSSH(NoConfig, BaseConnection):
+ """
+ Implements methods for communicating with Check Point Gaia
+ firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="set clienv rows 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CheckPointGaiaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements methods for communicating with Check Point Gaia
+firewalls.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CheckPointGaiaSSH(NoConfig, BaseConnection):
+ """
+ Implements methods for communicating with Check Point Gaia
+ firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="set clienv rows 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+Set the base prompt for interaction ('>').
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="set clienv rows 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/checkpoint/index.html b/docs/netmiko/checkpoint/index.html
new file mode 100644
index 000000000..284a19e0b
--- /dev/null
+++ b/docs/netmiko/checkpoint/index.html
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+netmiko.checkpoint API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.checkpoint
+
+
+
+Source code
+from netmiko.checkpoint.checkpoint_gaia_ssh import CheckPointGaiaSSH
+
+__all__ = ["CheckPointGaiaSSH"]
+
+
+
+
+
+
+
+
+
+class CheckPointGaiaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements methods for communicating with Check Point Gaia
+firewalls.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CheckPointGaiaSSH(NoConfig, BaseConnection):
+ """
+ Implements methods for communicating with Check Point Gaia
+ firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="set clienv rows 0")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+Set the base prompt for interaction ('>').
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="set clienv rows 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ciena/ciena_saos.html b/docs/netmiko/ciena/ciena_saos.html
new file mode 100644
index 000000000..f8de7150f
--- /dev/null
+++ b/docs/netmiko/ciena/ciena_saos.html
@@ -0,0 +1,1093 @@
+
+
+
+
+
+
+netmiko.ciena.ciena_saos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ciena.ciena_saos
+
+
+Ciena SAOS support.
+
+Source code
+"""Ciena SAOS support."""
+from typing import Optional, Any
+import re
+import os
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+from netmiko.scp_handler import BaseFileTransfer
+
+
+class CienaSaosBase(NoEnable, NoConfig, BaseConnection):
+ """
+ Ciena SAOS support.
+
+ Implements methods for interacting Ciena Saos devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="system shell session set more off")
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ output = self._send_command_str("diag shell", expect_string=r"[$#>]")
+ if "SHELL PARSER FAILURE" in output:
+ msg = "SCP support on Ciena SAOS requires 'diag shell' permissions"
+ raise ValueError(msg)
+ return output
+
+ def _return_cli(self) -> str:
+ """Return to the Ciena SAOS CLI."""
+ return self._send_command_str("exit", expect_string=r"[>]")
+
+ def save_config(
+ self,
+ cmd: str = "configuration save",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CienaSaosSSH(CienaSaosBase):
+ pass
+
+
+class CienaSaosTelnet(CienaSaosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class CienaSaosFileTransfer(BaseFileTransfer):
+ """Ciena SAOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ if file_system is None:
+ file_system = f"/tmp/users/{ssh_conn.username}"
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"file ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = re.escape(f"{self.file_system}/{self.dest_file}")
+ if "ERROR" in remote_out:
+ return False
+ elif re.search(search_string, remote_out):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+
+ remote_file = f"{self.file_system}/{remote_file}"
+
+ if not remote_cmd:
+ remote_cmd = f"file ls -l {remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if base_cmd == "":
+ base_cmd = "md5sum"
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ dest_md5 = self.ssh_ctl_chan._send_command_str(
+ remote_md5_cmd, expect_string=r"[$#>]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ dest_md5 = self.process_md5(dest_md5, pattern=r"([0-9a-f]+)\s+")
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "system server scp enable") -> None:
+ return super().enable_scp(cmd=cmd)
+
+ def disable_scp(self, cmd: str = "system server scp disable") -> None:
+ return super().disable_scp(cmd=cmd)
+
+
+
+
+
+
+
+
+
+class CienaSaosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ciena SAOS support.
+Implements methods for interacting Ciena Saos devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CienaSaosBase(NoEnable, NoConfig, BaseConnection):
+ """
+ Ciena SAOS support.
+
+ Implements methods for interacting Ciena Saos devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="system shell session set more off")
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ output = self._send_command_str("diag shell", expect_string=r"[$#>]")
+ if "SHELL PARSER FAILURE" in output:
+ msg = "SCP support on Ciena SAOS requires 'diag shell' permissions"
+ raise ValueError(msg)
+ return output
+
+ def _return_cli(self) -> str:
+ """Return to the Ciena SAOS CLI."""
+ return self._send_command_str("exit", expect_string=r"[>]")
+
+ def save_config(
+ self,
+ cmd: str = "configuration save",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='configuration save', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "configuration save",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class CienaSaosFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', **kwargs)
+
+-
+
Ciena SAOS SCP File Transfer driver.
+
+Source code
+class CienaSaosFileTransfer(BaseFileTransfer):
+ """Ciena SAOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ if file_system is None:
+ file_system = f"/tmp/users/{ssh_conn.username}"
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"file ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = re.escape(f"{self.file_system}/{self.dest_file}")
+ if "ERROR" in remote_out:
+ return False
+ elif re.search(search_string, remote_out):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+
+ remote_file = f"{self.file_system}/{remote_file}"
+
+ if not remote_cmd:
+ remote_cmd = f"file ls -l {remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if base_cmd == "":
+ base_cmd = "md5sum"
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ dest_md5 = self.ssh_ctl_chan._send_command_str(
+ remote_md5_cmd, expect_string=r"[$#>]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ dest_md5 = self.process_md5(dest_md5, pattern=r"([0-9a-f]+)\s+")
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "system server scp enable") -> None:
+ return super().enable_scp(cmd=cmd)
+
+ def disable_scp(self, cmd: str = "system server scp disable") -> None:
+ return super().disable_scp(cmd=cmd)
+
+Ancestors
+
+Methods
+
+
+def remote_space_available(self, search_pattern='')
+
+-
+
Return space available on Ciena SAOS
+Output should only have the file-system that matches {self.file_system}
+Filesystem
+1K-blocks
+Used Available Use% Mounted on
+tmpfs
+1048576
+648
+1047928
+0% /tmp
+
+Source code
+def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+
+
+Inherited members
+
+
+
+class CienaSaosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ciena SAOS support.
+Implements methods for interacting Ciena Saos devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CienaSaosSSH(CienaSaosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CienaSaosTelnet
+(*args, **kwargs)
+
+-
+
Ciena SAOS support.
+Implements methods for interacting Ciena Saos devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CienaSaosTelnet(CienaSaosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ciena/ciena_saos_ssh.html b/docs/netmiko/ciena/ciena_saos_ssh.html
new file mode 100644
index 000000000..fc7a70fac
--- /dev/null
+++ b/docs/netmiko/ciena/ciena_saos_ssh.html
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+netmiko.ciena.ciena_saos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ciena.ciena_saos_ssh
+
+
+Ciena SAOS support.
+
+Source code
+"""Ciena SAOS support."""
+from __future__ import print_function
+from __future__ import unicode_literals
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CienaSaosSSH(CiscoSSHConnection):
+ """Ciena SAOS support."""
+
+ def session_preparation(self):
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="system shell session set more off")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(self, *args, **kwargs):
+ pass
+
+ def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CienaSaosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, 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, timeout=100, session_timeout=60, auth_timeout=None, blocking_timeout=8, banner_timeout=5, 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')
+
+-
+
Ciena SAOS 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
+
+
+Source code
+class CienaSaosSSH(CiscoSSHConnection):
+ """Ciena SAOS support."""
+
+ def session_preparation(self):
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="system shell session set more off")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(self, *args, **kwargs):
+ pass
+
+ def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args, **kwargs):
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ciena/index.html b/docs/netmiko/ciena/index.html
new file mode 100644
index 000000000..f38b15400
--- /dev/null
+++ b/docs/netmiko/ciena/index.html
@@ -0,0 +1,678 @@
+
+
+
+
+
+
+netmiko.ciena API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.ciena.ciena_saos import (
+ CienaSaosSSH,
+ CienaSaosTelnet,
+ CienaSaosFileTransfer,
+)
+
+__all__ = ["CienaSaosSSH", "CienaSaosTelnet", "CienaSaosFileTransfer"]
+
+
+
+
+
+
+
+
+
+class CienaSaosFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', **kwargs)
+
+-
+
Ciena SAOS SCP File Transfer driver.
+
+Source code
+class CienaSaosFileTransfer(BaseFileTransfer):
+ """Ciena SAOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ if file_system is None:
+ file_system = f"/tmp/users/{ssh_conn.username}"
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"file ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = re.escape(f"{self.file_system}/{self.dest_file}")
+ if "ERROR" in remote_out:
+ return False
+ elif re.search(search_string, remote_out):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+
+ remote_file = f"{self.file_system}/{remote_file}"
+
+ if not remote_cmd:
+ remote_cmd = f"file ls -l {remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if base_cmd == "":
+ base_cmd = "md5sum"
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ dest_md5 = self.ssh_ctl_chan._send_command_str(
+ remote_md5_cmd, expect_string=r"[$#>]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ dest_md5 = self.process_md5(dest_md5, pattern=r"([0-9a-f]+)\s+")
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "system server scp enable") -> None:
+ return super().enable_scp(cmd=cmd)
+
+ def disable_scp(self, cmd: str = "system server scp disable") -> None:
+ return super().disable_scp(cmd=cmd)
+
+Ancestors
+
+Methods
+
+
+def remote_space_available(self, search_pattern='')
+
+-
+
Return space available on Ciena SAOS
+Output should only have the file-system that matches {self.file_system}
+Filesystem
+1K-blocks
+Used Available Use% Mounted on
+tmpfs
+1048576
+648
+1047928
+0% /tmp
+
+Source code
+def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+
+
+Inherited members
+
+
+
+class CienaSaosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ciena SAOS support.
+Implements methods for interacting Ciena Saos devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CienaSaosSSH(CienaSaosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CienaSaosTelnet
+(*args, **kwargs)
+
+-
+
Ciena SAOS support.
+Implements methods for interacting Ciena Saos devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CienaSaosTelnet(CienaSaosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_asa_ssh.html b/docs/netmiko/cisco/cisco_asa_ssh.html
new file mode 100644
index 000000000..4754f10fe
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_asa_ssh.html
@@ -0,0 +1,820 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_asa_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_asa_ssh
+
+
+Subclass specific to Cisco ASA.
+
+Source code
+"""Subclass specific to Cisco ASA."""
+from typing import Any, Union, List, Dict, Optional
+import re
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class CiscoAsaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco ASA."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ kwargs.setdefault("allow_auto_change", True)
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """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:
+ self.asa_login()
+ self.disable_paging(command="terminal pager 0")
+
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def send_command_timing(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ output = super().send_command_timing(*args, **kwargs)
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+ if "changeto" in command_string:
+ self.set_base_prompt()
+ return output
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+
+ # If changeto in command, look for '#' to determine command is done
+ if "changeto" in command_string:
+ if len(args) <= 1:
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
+
+ if "changeto" in command_string:
+ self.set_base_prompt()
+
+ return output
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Cisco ASA in multi-context mode needs to have the base prompt updated
+ (if you switch contexts i.e. 'changeto')
+
+ This switch of ASA contexts can occur in configuration mode. If this
+ happens the trailing '(config*' needs stripped off.
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
+ if match:
+ # strip off (conf.* from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return cur_base_prompt
+
+ def asa_login(self) -> None:
+ """
+ Handle ASA reaching privilege level 15 using login
+
+ twb-dc-fw1> login
+ Username: admin
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
+ """
+ delay_factor = self.select_delay_factor(0)
+
+ 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()
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ elif "#" in output:
+ return
+ else:
+ self.write_channel("login" + self.RETURN)
+ i += 1
+
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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."""
+
+ pass
+
+
+
+
+
+
+
+
+
+class CiscoAsaFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco ASA SCP File Transfer driver.
+
+Source code
+class CiscoAsaFileTransfer(CiscoFileTransfer):
+ """Cisco ASA SCP File Transfer driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoAsaSSH
+(*args, **kwargs)
+
+-
+
Subclass specific to Cisco ASA.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoAsaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco ASA."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ kwargs.setdefault("allow_auto_change", True)
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """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:
+ self.asa_login()
+ self.disable_paging(command="terminal pager 0")
+
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def send_command_timing(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ output = super().send_command_timing(*args, **kwargs)
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+ if "changeto" in command_string:
+ self.set_base_prompt()
+ return output
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+
+ # If changeto in command, look for '#' to determine command is done
+ if "changeto" in command_string:
+ if len(args) <= 1:
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
+
+ if "changeto" in command_string:
+ self.set_base_prompt()
+
+ return output
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Cisco ASA in multi-context mode needs to have the base prompt updated
+ (if you switch contexts i.e. 'changeto')
+
+ This switch of ASA contexts can occur in configuration mode. If this
+ happens the trailing '(config*' needs stripped off.
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
+ if match:
+ # strip off (conf.* from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return cur_base_prompt
+
+ def asa_login(self) -> None:
+ """
+ Handle ASA reaching privilege level 15 using login
+
+ twb-dc-fw1> login
+ Username: admin
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
+ """
+ delay_factor = self.select_delay_factor(0)
+
+ 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()
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ elif "#" in output:
+ return
+ else:
+ self.write_channel("login" + self.RETURN)
+ i += 1
+
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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
+
+Methods
+
+
+def asa_login(self)
+
+-
+
Handle ASA reaching privilege level 15 using login
+twb-dc-fw1> login
+Username: admin
+Raises NetmikoAuthenticationException, if we do not reach privilege
+level 15 after 10 loops.
+
+Source code
+def asa_login(self) -> None:
+ """
+ Handle ASA reaching privilege level 15 using login
+
+ twb-dc-fw1> login
+ Username: admin
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
+ """
+ delay_factor = self.select_delay_factor(0)
+
+ 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()
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ elif "#" in output:
+ return
+ else:
+ self.write_channel("login" + self.RETURN)
+ i += 1
+
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Cisco ASA needed that extra
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """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='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def send_command(self, *args, **kwargs)
+
+-
+
If the ASA is in multi-context mode, then the base_prompt needs to be
+updated after each context change.
+
+Source code
+def send_command(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+
+ # If changeto in command, look for '#' to determine command is done
+ if "changeto" in command_string:
+ if len(args) <= 1:
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
+
+ if "changeto" in command_string:
+ self.set_base_prompt()
+
+ return output
+
+
+
+def send_command_timing(self, *args, **kwargs)
+
+-
+
If the ASA is in multi-context mode, then the base_prompt needs to be
+updated after each context change.
+
+Source code
+def send_command_timing(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ output = super().send_command_timing(*args, **kwargs)
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+ if "changeto" in command_string:
+ self.set_base_prompt()
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """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:
+ self.asa_login()
+ self.disable_paging(command="terminal pager 0")
+
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+
+
+def set_base_prompt(self, *args, **kwargs)
+
+-
+
Cisco ASA in multi-context mode needs to have the base prompt updated
+(if you switch contexts i.e. 'changeto')
+This switch of ASA contexts can occur in configuration mode. If this
+happens the trailing '(config*' needs stripped off.
+
+Source code
+def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Cisco ASA in multi-context mode needs to have the base prompt updated
+ (if you switch contexts i.e. 'changeto')
+
+ This switch of ASA contexts can occur in configuration mode. If this
+ happens the trailing '(config*' needs stripped off.
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
+ if match:
+ # strip off (conf.* from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return cur_base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_ftd_ssh.html b/docs/netmiko/cisco/cisco_ftd_ssh.html
new file mode 100644
index 000000000..847ee71f7
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_ftd_ssh.html
@@ -0,0 +1,315 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_ftd_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_ftd_ssh
+
+
+Subclass specific to Cisco FTD.
+
+Source code
+"""Subclass specific to Cisco FTD."""
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoFtdSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Subclass specific to Cisco FTD."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
+
+
+
+
+
+
+
+
+
+class CiscoFtdSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Subclass specific to Cisco FTD.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoFtdSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Subclass specific to Cisco FTD."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
Canot change config on FTD via ssh
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
+
+
+
+def send_config_set(self, *args, **kwargs)
+
+-
+
Canot change config on FTD via ssh
+
+Source code
+def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_ios.html b/docs/netmiko/cisco/cisco_ios.html
new file mode 100644
index 000000000..1e6f961ec
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_ios.html
@@ -0,0 +1,1422 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_ios API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_ios
+
+
+
+Source code
+from typing import Any, Optional, Callable, Type
+from types import TracebackType
+import time
+import re
+import os
+import hashlib
+import io
+
+from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
+from netmiko.base_connection import BaseConnection
+
+
+class CiscoIosBase(CiscoBaseConnection):
+ """Common Methods for IOS (both SSH and telnet)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = r"#") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CiscoIosSSH(CiscoIosBase):
+ """Cisco IOS SSH driver."""
+
+ pass
+
+
+class CiscoIosTelnet(CiscoIosBase):
+ """Cisco IOS Telnet driver."""
+
+ pass
+
+
+class CiscoIosSerial(CiscoIosBase):
+ """Cisco IOS Serial driver."""
+
+ pass
+
+
+class CiscoIosFileTransfer(CiscoFileTransfer):
+ """Cisco IOS SCP File Transfer driver."""
+
+ pass
+
+
+class InLineTransfer(CiscoIosFileTransfer):
+ """Use TCL on Cisco IOS to directly transfer file."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str = "",
+ dest_file: str = "",
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ source_config: Optional[str] = None,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+
+ if not dest_file:
+ raise ValueError(
+ "Destination file must be specified for InlineTransfer operations."
+ )
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for InLineTransfer")
+
+ if source_file and source_config:
+ msg = "Invalid call to InLineTransfer both source_file and source_config specified."
+ raise ValueError(msg)
+ if direction != "put":
+ raise ValueError("Only put operation supported by InLineTransfer.")
+
+ if progress is not None or progress4 is not None:
+ raise NotImplementedError(
+ "Progress bar is not supported on inline transfers."
+ )
+ else:
+ self.progress = progress
+ self.progress4 = progress4
+
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ if source_file:
+ self.source_config = None
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif source_config:
+ self.source_config = source_config
+ self.source_md5 = self.config_md5(source_config)
+ self.file_size = len(source_config.encode("UTF-8"))
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if not file_system:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ self.file_system = file_system
+
+ self.socket_timeout = socket_timeout
+
+ @staticmethod
+ def _read_file(file_name: str) -> str:
+ with io.open(file_name, "rt", encoding="utf-8") as f:
+ return f.read()
+
+ @staticmethod
+ def _tcl_newline_rationalize(tcl_string: str) -> str:
+ r"""
+ When using put inside a TCL {} section the newline is considered a new TCL
+ statement and causes a missing curly-brace message. Convert "\n" to "\r". TCL
+ will convert the "\r" to a "\n" i.e. you will see a "\n" inside the file on the
+ Cisco IOS device.
+ """
+ NEWLINE = r"\n"
+ CARRIAGE_RETURN = r"\r"
+ tmp_string = re.sub(NEWLINE, CARRIAGE_RETURN, tcl_string)
+ if re.search(r"[{}]", tmp_string):
+ msg = "Curly brace detected in string; TCL requires this be escaped."
+ raise ValueError(msg)
+ return tmp_string
+
+ def __enter__(self) -> "InLineTransfer":
+ self._enter_tcl_mode()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ self._exit_tcl_mode()
+
+ def _enter_tcl_mode(self) -> str:
+ TCL_ENTER = "tclsh"
+ cmd_failed = ['Translating "tclsh"', "% Unknown command", "% Bad IP address"]
+ output = self.ssh_ctl_chan._send_command_str(
+ TCL_ENTER,
+ expect_string=r"\(tcl\)#",
+ strip_prompt=False,
+ strip_command=False,
+ )
+ for pattern in cmd_failed:
+ if pattern in output:
+ raise ValueError(f"Failed to enter tclsh mode on router: {output}")
+ return output
+
+ def _exit_tcl_mode(self) -> str:
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel("\r")
+ time.sleep(1)
+ output = self.ssh_ctl_chan.read_channel()
+ if "(tcl)" in output:
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+ time.sleep(1)
+ output += self.ssh_ctl_chan.read_channel()
+ return output
+
+ def establish_scp_conn(self) -> None:
+ raise NotImplementedError
+
+ def close_scp_chan(self) -> None:
+ raise NotImplementedError
+
+ def local_space_available(self) -> bool:
+ raise NotImplementedError
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def put_file(self) -> None:
+ curlybrace = r"{"
+ TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(
+ self.file_system, self.dest_file, curlybrace
+ )
+ TCL_FILECMD_EXIT = "}"
+
+ if self.source_file:
+ file_contents = self._read_file(self.source_file)
+ elif self.source_config:
+ file_contents = self.source_config
+ file_contents = self._tcl_newline_rationalize(file_contents)
+
+ # Try to remove any existing data
+ self.ssh_ctl_chan.clear_buffer()
+
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_ENTER)
+ time.sleep(0.25)
+ self.ssh_ctl_chan.write_channel(file_contents)
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_EXIT + "\r")
+
+ # This operation can be slow (depends on the size of the file)
+ read_timeout = 100
+ sleep_time = 4
+ if self.file_size >= 2500:
+ read_timeout = 300
+ sleep_time = 12
+ elif self.file_size >= 7500:
+ read_timeout = 600
+ sleep_time = 25
+
+ # Initial delay
+ time.sleep(sleep_time)
+
+ # File paste and TCL_FILECMD_exit should be indicated by "router(tcl)#"
+ output = self.ssh_ctl_chan.read_until_pattern(
+ pattern=r"\(tcl\).*$", re_flags=re.M, read_timeout=read_timeout
+ )
+
+ # The file doesn't write until tclquit
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+
+ time.sleep(1)
+ # Read all data remaining from the TCLSH session
+ pattern = rf"tclquit.*{self.ssh_ctl_chan.base_prompt}.*$"
+ re_flags = re.DOTALL | re.M
+ output += self.ssh_ctl_chan.read_until_pattern(
+ pattern=pattern, re_flags=re_flags, read_timeout=read_timeout
+ )
+ return None
+
+ def get_file(self) -> None:
+ raise NotImplementedError
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CiscoIosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Common Methods for IOS (both SSH and telnet).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosBase(CiscoBaseConnection):
+ """Common Methods for IOS (both SSH and telnet)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = r"#") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write mem', confirm=False, confirm_response='')
+
+-
+
Saves Config Using Copy Run Start
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config Using Copy Run Start"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class CiscoIosFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco IOS SCP File Transfer driver.
+
+Source code
+class CiscoIosFileTransfer(CiscoFileTransfer):
+ """Cisco IOS SCP File Transfer driver."""
+
+ pass
+
+Ancestors
+
+Subclasses
+
+Inherited members
+
+
+
+class CiscoIosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosSSH(CiscoIosBase):
+ """Cisco IOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoIosSerial
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS Serial driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosSerial(CiscoIosBase):
+ """Cisco IOS Serial driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoIosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosTelnet(CiscoIosBase):
+ """Cisco IOS Telnet driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class InLineTransfer
+(ssh_conn, source_file='', dest_file='', file_system=None, direction='put', source_config=None, socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Use TCL on Cisco IOS to directly transfer file.
+
+Source code
+class InLineTransfer(CiscoIosFileTransfer):
+ """Use TCL on Cisco IOS to directly transfer file."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str = "",
+ dest_file: str = "",
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ source_config: Optional[str] = None,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+
+ if not dest_file:
+ raise ValueError(
+ "Destination file must be specified for InlineTransfer operations."
+ )
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for InLineTransfer")
+
+ if source_file and source_config:
+ msg = "Invalid call to InLineTransfer both source_file and source_config specified."
+ raise ValueError(msg)
+ if direction != "put":
+ raise ValueError("Only put operation supported by InLineTransfer.")
+
+ if progress is not None or progress4 is not None:
+ raise NotImplementedError(
+ "Progress bar is not supported on inline transfers."
+ )
+ else:
+ self.progress = progress
+ self.progress4 = progress4
+
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ if source_file:
+ self.source_config = None
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif source_config:
+ self.source_config = source_config
+ self.source_md5 = self.config_md5(source_config)
+ self.file_size = len(source_config.encode("UTF-8"))
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if not file_system:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ self.file_system = file_system
+
+ self.socket_timeout = socket_timeout
+
+ @staticmethod
+ def _read_file(file_name: str) -> str:
+ with io.open(file_name, "rt", encoding="utf-8") as f:
+ return f.read()
+
+ @staticmethod
+ def _tcl_newline_rationalize(tcl_string: str) -> str:
+ r"""
+ When using put inside a TCL {} section the newline is considered a new TCL
+ statement and causes a missing curly-brace message. Convert "\n" to "\r". TCL
+ will convert the "\r" to a "\n" i.e. you will see a "\n" inside the file on the
+ Cisco IOS device.
+ """
+ NEWLINE = r"\n"
+ CARRIAGE_RETURN = r"\r"
+ tmp_string = re.sub(NEWLINE, CARRIAGE_RETURN, tcl_string)
+ if re.search(r"[{}]", tmp_string):
+ msg = "Curly brace detected in string; TCL requires this be escaped."
+ raise ValueError(msg)
+ return tmp_string
+
+ def __enter__(self) -> "InLineTransfer":
+ self._enter_tcl_mode()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ self._exit_tcl_mode()
+
+ def _enter_tcl_mode(self) -> str:
+ TCL_ENTER = "tclsh"
+ cmd_failed = ['Translating "tclsh"', "% Unknown command", "% Bad IP address"]
+ output = self.ssh_ctl_chan._send_command_str(
+ TCL_ENTER,
+ expect_string=r"\(tcl\)#",
+ strip_prompt=False,
+ strip_command=False,
+ )
+ for pattern in cmd_failed:
+ if pattern in output:
+ raise ValueError(f"Failed to enter tclsh mode on router: {output}")
+ return output
+
+ def _exit_tcl_mode(self) -> str:
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel("\r")
+ time.sleep(1)
+ output = self.ssh_ctl_chan.read_channel()
+ if "(tcl)" in output:
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+ time.sleep(1)
+ output += self.ssh_ctl_chan.read_channel()
+ return output
+
+ def establish_scp_conn(self) -> None:
+ raise NotImplementedError
+
+ def close_scp_chan(self) -> None:
+ raise NotImplementedError
+
+ def local_space_available(self) -> bool:
+ raise NotImplementedError
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def put_file(self) -> None:
+ curlybrace = r"{"
+ TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(
+ self.file_system, self.dest_file, curlybrace
+ )
+ TCL_FILECMD_EXIT = "}"
+
+ if self.source_file:
+ file_contents = self._read_file(self.source_file)
+ elif self.source_config:
+ file_contents = self.source_config
+ file_contents = self._tcl_newline_rationalize(file_contents)
+
+ # Try to remove any existing data
+ self.ssh_ctl_chan.clear_buffer()
+
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_ENTER)
+ time.sleep(0.25)
+ self.ssh_ctl_chan.write_channel(file_contents)
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_EXIT + "\r")
+
+ # This operation can be slow (depends on the size of the file)
+ read_timeout = 100
+ sleep_time = 4
+ if self.file_size >= 2500:
+ read_timeout = 300
+ sleep_time = 12
+ elif self.file_size >= 7500:
+ read_timeout = 600
+ sleep_time = 25
+
+ # Initial delay
+ time.sleep(sleep_time)
+
+ # File paste and TCL_FILECMD_exit should be indicated by "router(tcl)#"
+ output = self.ssh_ctl_chan.read_until_pattern(
+ pattern=r"\(tcl\).*$", re_flags=re.M, read_timeout=read_timeout
+ )
+
+ # The file doesn't write until tclquit
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+
+ time.sleep(1)
+ # Read all data remaining from the TCLSH session
+ pattern = rf"tclquit.*{self.ssh_ctl_chan.base_prompt}.*$"
+ re_flags = re.DOTALL | re.M
+ output += self.ssh_ctl_chan.read_until_pattern(
+ pattern=pattern, re_flags=re_flags, read_timeout=read_timeout
+ )
+ return None
+
+ def get_file(self) -> None:
+ raise NotImplementedError
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def config_md5(self, source_config)
+
+-
+
Compute MD5 hash of text.
+
+Source code
+def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+def file_md5(self, file_name, add_newline=False)
+
+-
+
Compute MD5 hash of file.
+
+Source code
+def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_nxos_ssh.html b/docs/netmiko/cisco/cisco_nxos_ssh.html
new file mode 100644
index 000000000..72011f5e0
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_nxos_ssh.html
@@ -0,0 +1,685 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_nxos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_nxos_ssh
+
+
+
+Source code
+from typing import Any, Optional, Callable
+import re
+import os
+from netmiko.base_connection import BaseConnection
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.cisco_base_connection import CiscoFileTransfer
+
+
+class CiscoNxosSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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|\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: str = ")#", pattern: str = "#") -> bool:
+ """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: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # NX-OS is very slow on save_config ensure it waits long enough.
+ output += self._send_command_str(
+ command_string=cmd,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=100,
+ )
+ return output
+
+
+class CiscoNxosFileTransfer(CiscoFileTransfer):
+ """Cisco NXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: str = "bootflash:",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for NX-OS")
+
+ if file_system:
+ self.file_system = file_system
+ else:
+ raise ValueError("Destination file system must be specified for NX-OS")
+
+ if direction == "put":
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif direction == "get":
+ self.source_md5 = self.remote_md5(remote_file=source_file)
+ self.file_size = self.remote_file_size(remote_file=source_file)
+ else:
+ raise ValueError("Invalid direction specified")
+
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"{}.*Usage for".format(self.dest_file)
+ if "No such file or directory" in remote_out:
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if re.search("no such file or directory", remote_out, flags=re.I):
+ raise IOError("Unable to find file on remote system")
+ # Match line containing file name
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ file_size = match.group(0)
+ file_size = file_size.split()[0]
+ return int(file_size)
+
+ raise IOError("Unable to find file on remote system")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
+ """Not needed on NX-OS."""
+ raise NotImplementedError
+
+ def remote_md5(
+ self, base_cmd: str = "show file", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}{remote_file} md5sum"
+ output = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ output = output.strip()
+ return output
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CiscoNxosFileTransfer
+(ssh_conn, source_file, dest_file, file_system='bootflash:', direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco NXOS SCP File Transfer driver.
+
+Source code
+class CiscoNxosFileTransfer(CiscoFileTransfer):
+ """Cisco NXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: str = "bootflash:",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for NX-OS")
+
+ if file_system:
+ self.file_system = file_system
+ else:
+ raise ValueError("Destination file system must be specified for NX-OS")
+
+ if direction == "put":
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif direction == "get":
+ self.source_md5 = self.remote_md5(remote_file=source_file)
+ self.file_size = self.remote_file_size(remote_file=source_file)
+ else:
+ raise ValueError("Invalid direction specified")
+
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"{}.*Usage for".format(self.dest_file)
+ if "No such file or directory" in remote_out:
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if re.search("no such file or directory", remote_out, flags=re.I):
+ raise IOError("Unable to find file on remote system")
+ # Match line containing file name
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ file_size = match.group(0)
+ file_size = file_size.split()[0]
+ return int(file_size)
+
+ raise IOError("Unable to find file on remote system")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
+ """Not needed on NX-OS."""
+ raise NotImplementedError
+
+ def remote_md5(
+ self, base_cmd: str = "show file", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}{remote_file} md5sum"
+ output = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ output = output.strip()
+ return output
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Static methods
+
+
+def process_md5(md5_output, pattern='= (.*)')
+
+-
+
+
+Source code
+@staticmethod
+def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
+ """Not needed on NX-OS."""
+ raise NotImplementedError
+
+
+
+Inherited members
+
+
+
+class CiscoNxosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoNxosSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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|\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: str = ")#", pattern: str = "#") -> bool:
+ """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: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # NX-OS is very slow on save_config ensure it waits long enough.
+ output += self._send_command_str(
+ command_string=cmd,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=100,
+ )
+ 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: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Convert '
+' or '
+' to '
+, and remove extra '
+'s in the text.
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """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|\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 session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
+ self.disable_paging()
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_s300.html b/docs/netmiko/cisco/cisco_s300.html
new file mode 100644
index 000000000..af25013d5
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_s300.html
@@ -0,0 +1,687 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_s300 API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_s300
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoS300Base(CiscoSSHConnection):
+ """
+ Support for Cisco SG300 series of devices.
+
+ Note, must configure the following to disable SG300 from prompting for username twice:
+
+ configure terminal
+ ip ssh password-auth
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging(command="terminal datadump")
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = True,
+ confirm_response: str = "Y",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CiscoS300SSH(CiscoS300Base):
+ pass
+
+
+class CiscoS300Telnet(CiscoS300Base):
+ """
+ Support for Cisco SG300 series of devices, with telnet.
+ Note: can be used with Sx200 series, with telnet enabled.
+ """
+
+ pass
+
+
+
+
+
+
+
+
+
+class CiscoS300Base
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Cisco SG300 series of devices.
+Note, must configure the following to disable SG300 from prompting for username twice:
+configure terminal
+ip ssh password-auth
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoS300Base(CiscoSSHConnection):
+ """
+ Support for Cisco SG300 series of devices.
+
+ Note, must configure the following to disable SG300 from prompting for username twice:
+
+ configure terminal
+ ip ssh password-auth
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging(command="terminal datadump")
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = True,
+ confirm_response: str = "Y",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ self.disable_paging(command="terminal datadump")
+
+
+
+Inherited members
+
+
+
+class CiscoS300SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Cisco SG300 series of devices.
+Note, must configure the following to disable SG300 from prompting for username twice:
+configure terminal
+ip ssh password-auth
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoS300SSH(CiscoS300Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoS300Telnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Cisco SG300 series of devices, with telnet.
+Note: can be used with Sx200 series, with telnet enabled.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoS300Telnet(CiscoS300Base):
+ """
+ Support for Cisco SG300 series of devices, with telnet.
+ Note: can be used with Sx200 series, with telnet enabled.
+ """
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_tp_tcce.html b/docs/netmiko/cisco/cisco_tp_tcce.html
new file mode 100644
index 000000000..0a7569cbd
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_tp_tcce.html
@@ -0,0 +1,543 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_tp_tcce API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_tp_tcce
+
+
+CiscoTpTcCeSSH Class
+Class to manage Cisco Telepresence Endpoint on TC/CE software release. Also working for Cisco
+Expressway/VCS
+Written by Ahmad Barrin
+Updated by Kirk Byers
+
+Source code
+"""
+CiscoTpTcCeSSH Class
+Class to manage Cisco Telepresence Endpoint on TC/CE software release. Also working for Cisco
+Expressway/VCS
+
+Written by Ahmad Barrin
+Updated by Kirk Byers
+"""
+from typing import Any, Union, List, Dict
+import time
+import re
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoTpTcCeSSH(CiscoSSHConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Paging is disabled by default."""
+ return ""
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some of vagaries that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self.set_base_prompt()
+ self.disable_paging()
+ self.set_terminal_width()
+ """
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as base_prompt."""
+ self.base_prompt = "OK"
+ return self.base_prompt
+
+ def find_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as standard prompt."""
+ return "OK"
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+ if re.search(expect_string, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Send command to network device retrieve output until router_prompt or expect_string
+
+ By default this method will keep waiting to receive data until the network device prompt is
+ detected. The current network device prompt will be determined automatically.
+ """
+ if len(args) >= 2:
+ expect_string = args[1]
+ else:
+ expect_string = kwargs.get("expect_string")
+ if expect_string is None:
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
+ expect_string = self.RETURN + expect_string + self.RETURN
+ kwargs.setdefault("expect_string", expect_string)
+
+ output = super().send_command(*args, **kwargs)
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CiscoTpTcCeSSH
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoTpTcCeSSH(CiscoSSHConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Paging is disabled by default."""
+ return ""
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some of vagaries that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self.set_base_prompt()
+ self.disable_paging()
+ self.set_terminal_width()
+ """
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as base_prompt."""
+ self.base_prompt = "OK"
+ return self.base_prompt
+
+ def find_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as standard prompt."""
+ return "OK"
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+ if re.search(expect_string, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Send command to network device retrieve output until router_prompt or expect_string
+
+ By default this method will keep waiting to receive data until the network device prompt is
+ detected. The current network device prompt will be determined automatically.
+ """
+ if len(args) >= 2:
+ expect_string = args[1]
+ else:
+ expect_string = kwargs.get("expect_string")
+ if expect_string is None:
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
+ expect_string = self.RETURN + expect_string + self.RETURN
+ kwargs.setdefault("expect_string", expect_string)
+
+ output = super().send_command(*args, **kwargs)
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Paging is disabled by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Paging is disabled by default."""
+ return ""
+
+
+
+def find_prompt(self, *args, **kwargs)
+
+-
+
Use 'OK' as standard prompt.
+
+Source code
+def find_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as standard prompt."""
+ return "OK"
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_command(self, *args, **kwargs)
+
+-
+
Send command to network device retrieve output until router_prompt or expect_string
+By default this method will keep waiting to receive data until the network device prompt is
+detected. The current network device prompt will be determined automatically.
+
+Source code
+def send_command(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Send command to network device retrieve output until router_prompt or expect_string
+
+ By default this method will keep waiting to receive data until the network device prompt is
+ detected. The current network device prompt will be determined automatically.
+ """
+ if len(args) >= 2:
+ expect_string = args[1]
+ else:
+ expect_string = kwargs.get("expect_string")
+ if expect_string is None:
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
+ expect_string = self.RETURN + expect_string + self.RETURN
+ kwargs.setdefault("expect_string", expect_string)
+
+ output = super().send_command(*args, **kwargs)
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+This method handles some of vagaries that occur between various devices
+early on in the session.
+In general, it should include:
+self.set_base_prompt()
+self.disable_paging()
+self.set_terminal_width()
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some of vagaries that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self.set_base_prompt()
+ self.disable_paging()
+ self.set_terminal_width()
+ """
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, *args, **kwargs)
+
+-
+
+
+Source code
+def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as base_prompt."""
+ self.base_prompt = "OK"
+ return self.base_prompt
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+ if re.search(expect_string, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_viptela.html b/docs/netmiko/cisco/cisco_viptela.html
new file mode 100644
index 000000000..49afd7fa4
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_viptela.html
@@ -0,0 +1,471 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_viptela API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_viptela
+
+
+Subclass specific to Cisco Viptela.
+
+Source code
+"""Subclass specific to Cisco Viptela."""
+from typing import Union, Sequence, TextIO, Any
+import re
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoViptelaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco Viptela."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def commit(self, confirm: bool = False, confirm_response: str = "") -> str:
+ cmd = "commit"
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def config_mode(
+ self,
+ config_command: str = "conf terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CiscoViptelaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Subclass specific to Cisco Viptela.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoViptelaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco Viptela."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def commit(self, confirm: bool = False, confirm_response: str = "") -> str:
+ cmd = "commit"
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def config_mode(
+ self,
+ config_command: str = "conf terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ raise NotImplementedError
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def exit_config_mode(self, exit_config='end', pattern='#')
+
+-
+
Exit from configuration mode.
+Viptela might have the following in the output (if no 'commit()' occurred.
+Uncommitted changes found, commit them? [yes/no/CANCEL]
+
+Source code
+def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+
+
+def save_config(self, cmd='commit', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_wlc_ssh.html b/docs/netmiko/cisco/cisco_wlc_ssh.html
new file mode 100644
index 000000000..8016ec807
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_wlc_ssh.html
@@ -0,0 +1,953 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_wlc_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_wlc_ssh
+
+
+Netmiko Cisco WLC support.
+
+Source code
+"""Netmiko Cisco WLC support."""
+from typing import Any, Union, Sequence, TextIO
+import time
+import re
+import socket
+
+from netmiko.exceptions import NetmikoAuthenticationException
+from netmiko.base_connection import BaseConnection
+
+
+class CiscoWlcSSH(BaseConnection):
+ """Netmiko Cisco WLC support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ # WLC/AireOS has an issue where you can get "No Existing Session" with
+ # the default conn_timeout (so increase conn_timeout to 10-seconds).
+ kwargs.setdefault("conn_timeout", 10)
+ return super().__init__(*args, **kwargs)
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """WLC presents with the following on login (in certain OS versions)
+
+ login as: user
+
+ (Cisco Controller)
+
+ User: user
+
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ # no output read, sleep and go for one more round of read channel
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+ def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
+ Even though pagination is disabled
+ show run-config also has excessive delays in the output which requires special
+ handling.
+ Arguments are the same as send_command_timing() method
+ """
+ if len(args) > 1:
+ raise ValueError("Must pass in delay_factor as keyword argument")
+
+ # If no delay_factor use 1 for default value
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
+
+ if "Press any key" in output or "Press Enter to" in output:
+ new_args = list(args)
+ if len(args) == 1:
+ new_args[0] = self.RETURN
+ else:
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
+
+ # Send an 'enter'
+ output += self._send_command_timing_str(*new_args, **kwargs)
+
+ # WLC has excessive delay after this appears on screen
+ if "802.11b Advanced Configuration" in output:
+
+ # Defaults to 30 seconds
+ time.sleep(kwargs["delay_factor"] * 30)
+ not_done = True
+ i = 1
+ while not_done and i <= 150:
+ time.sleep(kwargs["delay_factor"] * 3)
+ i += 1
+ new_data = ""
+ new_data = self.read_channel()
+ if new_data:
+ output += new_data
+ else:
+ not_done = False
+
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ Cisco WLC uses "config paging disable" to disable paging
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ self.disable_paging(command="config paging disable")
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
+ self.send_command_timing("config paging enable")
+
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+ def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+ ) -> bool:
+ """Checks if the device is in configuration mode or not."""
+ if not pattern:
+ pattern = re.escape(self.base_prompt)
+ return super().check_config_mode(check_string, pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit config_mode."""
+ return super().exit_config_mode(exit_config, pattern)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs,
+ )
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+
+
+
+
+
+
+
+
+class CiscoWlcSSH
+(*args, **kwargs)
+
+-
+
Netmiko Cisco WLC support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoWlcSSH(BaseConnection):
+ """Netmiko Cisco WLC support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ # WLC/AireOS has an issue where you can get "No Existing Session" with
+ # the default conn_timeout (so increase conn_timeout to 10-seconds).
+ kwargs.setdefault("conn_timeout", 10)
+ return super().__init__(*args, **kwargs)
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """WLC presents with the following on login (in certain OS versions)
+
+ login as: user
+
+ (Cisco Controller)
+
+ User: user
+
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ # no output read, sleep and go for one more round of read channel
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+ def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
+ Even though pagination is disabled
+ show run-config also has excessive delays in the output which requires special
+ handling.
+ Arguments are the same as send_command_timing() method
+ """
+ if len(args) > 1:
+ raise ValueError("Must pass in delay_factor as keyword argument")
+
+ # If no delay_factor use 1 for default value
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
+
+ if "Press any key" in output or "Press Enter to" in output:
+ new_args = list(args)
+ if len(args) == 1:
+ new_args[0] = self.RETURN
+ else:
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
+
+ # Send an 'enter'
+ output += self._send_command_timing_str(*new_args, **kwargs)
+
+ # WLC has excessive delay after this appears on screen
+ if "802.11b Advanced Configuration" in output:
+
+ # Defaults to 30 seconds
+ time.sleep(kwargs["delay_factor"] * 30)
+ not_done = True
+ i = 1
+ while not_done and i <= 150:
+ time.sleep(kwargs["delay_factor"] * 3)
+ i += 1
+ new_data = ""
+ new_data = self.read_channel()
+ if new_data:
+ output += new_data
+ else:
+ not_done = False
+
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ Cisco WLC uses "config paging disable" to disable paging
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ self.disable_paging(command="config paging disable")
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
+ self.send_command_timing("config paging enable")
+
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+ def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+ ) -> bool:
+ """Checks if the device is in configuration mode or not."""
+ if not pattern:
+ pattern = re.escape(self.base_prompt)
+ return super().check_config_mode(check_string, pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit config_mode."""
+ return super().exit_config_mode(exit_config, pattern)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs,
+ )
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='config', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+
+Source code
+def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+) -> bool:
+ """Checks if the device is in configuration mode or not."""
+ if not pattern:
+ pattern = re.escape(self.base_prompt)
+ return super().check_config_mode(check_string, pattern)
+
+
+
+def cleanup(self, command='logout')
+
+-
+
Reset WLC back to normal paging and gracefully close session.
+
+Source code
+def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
+ self.send_command_timing("config paging enable")
+
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+
+
+def config_mode(self, config_command='config', pattern='', re_flags=0)
+
+-
+
+
+Source code
+def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter into config_mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit config_mode."""
+ return super().exit_config_mode(exit_config, pattern)
+
+
+
+def save_config(self, cmd='save config', confirm=True, confirm_response='y')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+
+
+def send_command_w_enter(self, *args, **kwargs)
+
+-
+
For 'show run-config' Cisco WLC adds a 'Press Enter to continue…' message
+Even though pagination is disabled
+show run-config also has excessive delays in the output which requires special
+handling.
+Arguments are the same as send_command_timing() method
+
+Source code
+def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
+ Even though pagination is disabled
+ show run-config also has excessive delays in the output which requires special
+ handling.
+ Arguments are the same as send_command_timing() method
+ """
+ if len(args) > 1:
+ raise ValueError("Must pass in delay_factor as keyword argument")
+
+ # If no delay_factor use 1 for default value
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
+
+ if "Press any key" in output or "Press Enter to" in output:
+ new_args = list(args)
+ if len(args) == 1:
+ new_args[0] = self.RETURN
+ else:
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
+
+ # Send an 'enter'
+ output += self._send_command_timing_str(*new_args, **kwargs)
+
+ # WLC has excessive delay after this appears on screen
+ if "802.11b Advanced Configuration" in output:
+
+ # Defaults to 30 seconds
+ time.sleep(kwargs["delay_factor"] * 30)
+ not_done = True
+ i = 1
+ while not_done and i <= 150:
+ time.sleep(kwargs["delay_factor"] * 3)
+ i += 1
+ new_data = ""
+ new_data = self.read_channel()
+ if new_data:
+ output += new_data
+ else:
+ not_done = False
+
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+
+
+def send_command_w_yes(self, *args, **kwargs)
+
+-
+
For 'show interface summary' Cisco WLC adds a
+'Would you like to display the next 15 entries?' message
+Even though pagination is disabled
+Arguments are the same as send_command_timing() method
+
+Source code
+def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+Cisco WLC uses "config paging disable" to disable paging
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ Cisco WLC uses "config paging disable" to disable paging
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ self.disable_paging(command="config paging disable")
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
WLC presents with the following on login (in certain OS versions)
+login as: user
+(Cisco Controller)
+User: user
+Password:****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """WLC presents with the following on login (in certain OS versions)
+
+ login as: user
+
+ (Cisco Controller)
+
+ User: user
+
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ # no output read, sleep and go for one more round of read channel
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_xr.html b/docs/netmiko/cisco/cisco_xr.html
new file mode 100644
index 000000000..d93a0dee1
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_xr.html
@@ -0,0 +1,1402 @@
+
+
+
+
+
+
+netmiko.cisco.cisco_xr API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco.cisco_xr
+
+
+
+Source code
+from typing import Optional, Any, Union, Sequence, TextIO
+import re
+import warnings
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
+
+
+class CiscoXrBase(CiscoBaseConnection):
+ def establish_connection(self, width: int = 511, height: int = 511) -> None:
+ """Establish SSH connection to the network device"""
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """IOS-XR requires you not exit from configuration mode."""
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ label: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ default (no options):
+ command_string = commit
+ confirm and confirm_delay:
+ command_string = commit confirmed <confirm_delay>
+ label (which is a label name):
+ command_string = commit label <label>
+ comment:
+ command_string = commit comment <comment>
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ supported combinations
+ label and confirm:
+ command_string = commit label <label> confirmed <confirm_delay>
+ label and comment:
+ command_string = commit label <label> comment <comment>
+
+ All other combinations will result in an exception.
+
+ failed commit message:
+ % Failed to commit one or more configuration items during a pseudo-atomic operation. All
+ changes made have been reverted. Please issue 'show configuration failed [inheritance]'
+ from this session to view the errors
+
+ message XR shows if other commits occurred:
+ One or more commits have occurred from other configuration sessions since this session
+ started or since the last commit was made from this session. You can use the 'show
+ configuration commit changes' command to browse the changes.
+
+ Exit of configuration mode with pending changes will cause the changes to be discarded and
+ an exception to be generated.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if confirm and not confirm_delay:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if confirm_delay and not confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if comment and confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+
+ label = str(label)
+ error_marker = "Failed to"
+ alt_error_marker = "One or more commits have occurred from other"
+
+ # Select proper command string based on arguments provided
+ if label:
+ if comment:
+ command_string = f"commit label {label} comment {comment}"
+ elif confirm:
+ command_string = "commit label {} confirmed {}".format(
+ label, str(confirm_delay)
+ )
+ else:
+ command_string = f"commit label {label}"
+ elif confirm:
+ command_string = f"commit confirmed {str(confirm_delay)}"
+ elif comment:
+ command_string = f"commit comment {comment}"
+ else:
+ command_string = "commit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+
+ # IOS-XR might do this:
+ # This could be a few minutes if your config is large. Confirm? [y/n][confirm]
+ new_data = self._send_command_str(
+ command_string,
+ expect_string=r"(#|onfirm)",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ if "onfirm" in new_data:
+ output += new_data
+ new_data = self._send_command_str(
+ "y",
+ expect_string=r"#",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ output += new_data
+ if error_marker in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ if alt_error_marker in output:
+ # Other commits occurred, don't proceed with commit
+ output += self._send_command_timing_str(
+ "no", strip_prompt=False, strip_command=False
+ )
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ IOS-XR, unfortunately, does this:
+ RP/0/RSP0/CPU0:BNG(admin)#
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ # Strip out (admin) so we don't get a false positive with (admin)#
+ # (admin-config)# would still match.
+ output = output.replace("(admin)", "")
+ return check_string in output
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_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"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+
+class CiscoXrSSH(CiscoXrBase):
+ """Cisco XR SSH driver."""
+
+ pass
+
+
+class CiscoXrTelnet(CiscoXrBase):
+ """Cisco XR Telnet driver."""
+
+ pass
+
+
+class CiscoXrFileTransfer(CiscoFileTransfer):
+ """Cisco IOS-XR SCP File Transfer driver."""
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
+ """
+ IOS-XR defaults with timestamps enabled
+
+ # show md5 file /bootflash:/boot/grub/grub.cfg
+ Sat Mar 3 17:49:03.596 UTC
+ c84843f0030efd44b01343fdb8c2e801
+ """
+ match = re.search(pattern, md5_output, flags=re.M)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+ def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+ ) -> str:
+ """
+ IOS-XR for MD5 requires this extra leading /
+
+ show md5 file /bootflash:/boot/grub/grub.cfg
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ # IOS-XR requires both the leading slash and the slash between file-system and file here
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CiscoXrBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoXrBase(CiscoBaseConnection):
+ def establish_connection(self, width: int = 511, height: int = 511) -> None:
+ """Establish SSH connection to the network device"""
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """IOS-XR requires you not exit from configuration mode."""
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ label: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ default (no options):
+ command_string = commit
+ confirm and confirm_delay:
+ command_string = commit confirmed <confirm_delay>
+ label (which is a label name):
+ command_string = commit label <label>
+ comment:
+ command_string = commit comment <comment>
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ supported combinations
+ label and confirm:
+ command_string = commit label <label> confirmed <confirm_delay>
+ label and comment:
+ command_string = commit label <label> comment <comment>
+
+ All other combinations will result in an exception.
+
+ failed commit message:
+ % Failed to commit one or more configuration items during a pseudo-atomic operation. All
+ changes made have been reverted. Please issue 'show configuration failed [inheritance]'
+ from this session to view the errors
+
+ message XR shows if other commits occurred:
+ One or more commits have occurred from other configuration sessions since this session
+ started or since the last commit was made from this session. You can use the 'show
+ configuration commit changes' command to browse the changes.
+
+ Exit of configuration mode with pending changes will cause the changes to be discarded and
+ an exception to be generated.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if confirm and not confirm_delay:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if confirm_delay and not confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if comment and confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+
+ label = str(label)
+ error_marker = "Failed to"
+ alt_error_marker = "One or more commits have occurred from other"
+
+ # Select proper command string based on arguments provided
+ if label:
+ if comment:
+ command_string = f"commit label {label} comment {comment}"
+ elif confirm:
+ command_string = "commit label {} confirmed {}".format(
+ label, str(confirm_delay)
+ )
+ else:
+ command_string = f"commit label {label}"
+ elif confirm:
+ command_string = f"commit confirmed {str(confirm_delay)}"
+ elif comment:
+ command_string = f"commit comment {comment}"
+ else:
+ command_string = "commit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+
+ # IOS-XR might do this:
+ # This could be a few minutes if your config is large. Confirm? [y/n][confirm]
+ new_data = self._send_command_str(
+ command_string,
+ expect_string=r"(#|onfirm)",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ if "onfirm" in new_data:
+ output += new_data
+ new_data = self._send_command_str(
+ "y",
+ expect_string=r"#",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ output += new_data
+ if error_marker in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ if alt_error_marker in output:
+ # Other commits occurred, don't proceed with commit
+ output += self._send_command_timing_str(
+ "no", strip_prompt=False, strip_command=False
+ )
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ IOS-XR, unfortunately, does this:
+ RP/0/RSP0/CPU0:BNG(admin)#
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ # Strip out (admin) so we don't get a false positive with (admin)#
+ # (admin-config)# would still match.
+ output = output.replace("(admin)", "")
+ return check_string in output
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_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"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=')#', pattern='[#\\$]')
+
+-
+
Checks if the device is in configuration mode or not.
+IOS-XR, unfortunately, does this:
+RP/0/RSP0/CPU0:BNG(admin)#
+
+Source code
+def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[#\$]"
+) -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ IOS-XR, unfortunately, does this:
+ RP/0/RSP0/CPU0:BNG(admin)#
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_pattern(pattern=pattern)
+ # Strip out (admin) so we don't get a false positive with (admin)#
+ # (admin-config)# would still match.
+ output = output.replace("(admin)", "")
+ return check_string in output
+
+
+
+def commit(self, confirm=False, confirm_delay=None, comment='', label='', read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+default (no options):
+command_string = commit
+confirm and confirm_delay:
+command_string = commit confirmed
+label (which is a label name):
+command_string = commit label
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+supported combinations
+label and confirm:
+command_string = commit label
+All other combinations will result in an exception.
+failed commit message:
+% Failed to commit one or more configuration items during a pseudo-atomic operation. All
+changes made have been reverted. Please issue 'show configuration failed [inheritance]'
+from this session to view the errors
+message XR shows if other commits occurred:
+One or more commits have occurred from other configuration sessions since this session
+started or since the last commit was made from this session. You can use the 'show
+configuration commit changes' command to browse the changes.
+Exit of configuration mode with pending changes will cause the changes to be discarded and
+an exception to be generated.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ label: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ default (no options):
+ command_string = commit
+ confirm and confirm_delay:
+ command_string = commit confirmed <confirm_delay>
+ label (which is a label name):
+ command_string = commit label <label>
+ comment:
+ command_string = commit comment <comment>
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ supported combinations
+ label and confirm:
+ command_string = commit label <label> confirmed <confirm_delay>
+ label and comment:
+ command_string = commit label <label> comment <comment>
+
+ All other combinations will result in an exception.
+
+ failed commit message:
+ % Failed to commit one or more configuration items during a pseudo-atomic operation. All
+ changes made have been reverted. Please issue 'show configuration failed [inheritance]'
+ from this session to view the errors
+
+ message XR shows if other commits occurred:
+ One or more commits have occurred from other configuration sessions since this session
+ started or since the last commit was made from this session. You can use the 'show
+ configuration commit changes' command to browse the changes.
+
+ Exit of configuration mode with pending changes will cause the changes to be discarded and
+ an exception to be generated.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if confirm and not confirm_delay:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if confirm_delay and not confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+ if comment and confirm:
+ raise ValueError("Invalid arguments supplied to XR commit")
+
+ label = str(label)
+ error_marker = "Failed to"
+ alt_error_marker = "One or more commits have occurred from other"
+
+ # Select proper command string based on arguments provided
+ if label:
+ if comment:
+ command_string = f"commit label {label} comment {comment}"
+ elif confirm:
+ command_string = "commit label {} confirmed {}".format(
+ label, str(confirm_delay)
+ )
+ else:
+ command_string = f"commit label {label}"
+ elif confirm:
+ command_string = f"commit confirmed {str(confirm_delay)}"
+ elif comment:
+ command_string = f"commit comment {comment}"
+ else:
+ command_string = "commit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+
+ # IOS-XR might do this:
+ # This could be a few minutes if your config is large. Confirm? [y/n][confirm]
+ new_data = self._send_command_str(
+ command_string,
+ expect_string=r"(#|onfirm)",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ if "onfirm" in new_data:
+ output += new_data
+ new_data = self._send_command_str(
+ "y",
+ expect_string=r"#",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ output += new_data
+ if error_marker in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ if alt_error_marker in output:
+ # Other commits occurred, don't proceed with commit
+ output += self._send_command_timing_str(
+ "no", strip_prompt=False, strip_command=False
+ )
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+
+
+def establish_connection(self, width=511, height=511)
+
+-
+
Establish SSH connection to the network device
+
+Source code
+def establish_connection(self, width: int = 511, height: int = 511) -> None:
+ """Establish SSH connection to the network device"""
+ super().establish_connection(width=width, height=height)
+
+
+
+def exit_config_mode(self, exit_config='end', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "end", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_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"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
Not Implemented (use commit() method)
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs)
+
+-
+
IOS-XR requires you not exit from configuration mode.
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """IOS-XR 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) -> None:
+ """Prepare the session after the connection has been established."""
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class CiscoXrFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco IOS-XR SCP File Transfer driver.
+
+Source code
+class CiscoXrFileTransfer(CiscoFileTransfer):
+ """Cisco IOS-XR SCP File Transfer driver."""
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
+ """
+ IOS-XR defaults with timestamps enabled
+
+ # show md5 file /bootflash:/boot/grub/grub.cfg
+ Sat Mar 3 17:49:03.596 UTC
+ c84843f0030efd44b01343fdb8c2e801
+ """
+ match = re.search(pattern, md5_output, flags=re.M)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+ def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+ ) -> str:
+ """
+ IOS-XR for MD5 requires this extra leading /
+
+ show md5 file /bootflash:/boot/grub/grub.cfg
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ # IOS-XR requires both the leading slash and the slash between file-system and file here
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Static methods
+
+
+def process_md5(md5_output, pattern='^([a-fA-F0-9]+)$')
+
+-
+
IOS-XR defaults with timestamps enabled
+show md5 file /bootflash:/boot/grub/grub.cfg
+Sat Mar
+3 17:49:03.596 UTC
+c84843f0030efd44b01343fdb8c2e801
+
+Source code
+@staticmethod
+def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
+ """
+ IOS-XR defaults with timestamps enabled
+
+ # show md5 file /bootflash:/boot/grub/grub.cfg
+ Sat Mar 3 17:49:03.596 UTC
+ c84843f0030efd44b01343fdb8c2e801
+ """
+ match = re.search(pattern, md5_output, flags=re.M)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+
+
+Methods
+
+
+def remote_md5(self, base_cmd='show md5 file', remote_file=None)
+
+-
+
IOS-XR for MD5 requires this extra leading /
+show md5 file /bootflash:/boot/grub/grub.cfg
+
+Source code
+def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+) -> str:
+ """
+ IOS-XR for MD5 requires this extra leading /
+
+ show md5 file /bootflash:/boot/grub/grub.cfg
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ # IOS-XR requires both the leading slash and the slash between file-system and file here
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+
+
+Inherited members
+
+
+
+-
+
Cisco XR SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoXrSSH(CiscoXrBase):
+ """Cisco XR SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoXrTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco XR Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoXrTelnet(CiscoXrBase):
+ """Cisco XR Telnet driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html
new file mode 100644
index 000000000..5b928666c
--- /dev/null
+++ b/docs/netmiko/cisco/index.html
@@ -0,0 +1,4736 @@
+
+
+
+
+
+
+netmiko.cisco API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.cisco.cisco_ios import (
+ CiscoIosBase,
+ CiscoIosSSH,
+ CiscoIosTelnet,
+ CiscoIosSerial,
+)
+from netmiko.cisco.cisco_ios import CiscoIosFileTransfer
+from netmiko.cisco.cisco_ios import InLineTransfer
+from netmiko.cisco.cisco_asa_ssh import CiscoAsaSSH, CiscoAsaFileTransfer
+from netmiko.cisco.cisco_ftd_ssh import CiscoFtdSSH
+from netmiko.cisco.cisco_nxos_ssh import CiscoNxosSSH, CiscoNxosFileTransfer
+from netmiko.cisco.cisco_xr import CiscoXrSSH, CiscoXrTelnet, CiscoXrFileTransfer
+from netmiko.cisco.cisco_wlc_ssh import CiscoWlcSSH
+from netmiko.cisco.cisco_s300 import CiscoS300SSH
+from netmiko.cisco.cisco_s300 import CiscoS300Telnet
+from netmiko.cisco.cisco_tp_tcce import CiscoTpTcCeSSH
+from netmiko.cisco.cisco_viptela import CiscoViptelaSSH
+
+__all__ = [
+ "CiscoIosSSH",
+ "CiscoIosTelnet",
+ "CiscoAsaSSH",
+ "CiscoFtdSSH",
+ "CiscoNxosSSH",
+ "CiscoXrSSH",
+ "CiscoXrTelnet",
+ "CiscoWlcSSH",
+ "CiscoS300SSH",
+ "CiscoS300Telnet",
+ "CiscoTpTcCeSSH",
+ "CiscoViptelaSSH",
+ "CiscoIosBase",
+ "CiscoIosFileTransfer",
+ "InLineTransfer",
+ "CiscoAsaFileTransfer",
+ "CiscoNxosFileTransfer",
+ "CiscoIosSerial",
+ "CiscoXrFileTransfer",
+]
+
+
+
+
+
+
+
+
+
+class CiscoAsaFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco ASA SCP File Transfer driver.
+
+Source code
+class CiscoAsaFileTransfer(CiscoFileTransfer):
+ """Cisco ASA SCP File Transfer driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoAsaSSH
+(*args, **kwargs)
+
+-
+
Subclass specific to Cisco ASA.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoAsaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco ASA."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ kwargs.setdefault("allow_auto_change", True)
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """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:
+ self.asa_login()
+ self.disable_paging(command="terminal pager 0")
+
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def send_command_timing(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ output = super().send_command_timing(*args, **kwargs)
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+ if "changeto" in command_string:
+ self.set_base_prompt()
+ return output
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+
+ # If changeto in command, look for '#' to determine command is done
+ if "changeto" in command_string:
+ if len(args) <= 1:
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
+
+ if "changeto" in command_string:
+ self.set_base_prompt()
+
+ return output
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Cisco ASA in multi-context mode needs to have the base prompt updated
+ (if you switch contexts i.e. 'changeto')
+
+ This switch of ASA contexts can occur in configuration mode. If this
+ happens the trailing '(config*' needs stripped off.
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
+ if match:
+ # strip off (conf.* from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return cur_base_prompt
+
+ def asa_login(self) -> None:
+ """
+ Handle ASA reaching privilege level 15 using login
+
+ twb-dc-fw1> login
+ Username: admin
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
+ """
+ delay_factor = self.select_delay_factor(0)
+
+ 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()
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ elif "#" in output:
+ return
+ else:
+ self.write_channel("login" + self.RETURN)
+ i += 1
+
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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
+
+Methods
+
+
+def asa_login(self)
+
+-
+
Handle ASA reaching privilege level 15 using login
+twb-dc-fw1> login
+Username: admin
+Raises NetmikoAuthenticationException, if we do not reach privilege
+level 15 after 10 loops.
+
+Source code
+def asa_login(self) -> None:
+ """
+ Handle ASA reaching privilege level 15 using login
+
+ twb-dc-fw1> login
+ Username: admin
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
+ """
+ delay_factor = self.select_delay_factor(0)
+
+ 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()
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ elif "#" in output:
+ return
+ else:
+ self.write_channel("login" + self.RETURN)
+ i += 1
+
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Cisco ASA needed that extra
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """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='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def send_command(self, *args, **kwargs)
+
+-
+
If the ASA is in multi-context mode, then the base_prompt needs to be
+updated after each context change.
+
+Source code
+def send_command(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+
+ # If changeto in command, look for '#' to determine command is done
+ if "changeto" in command_string:
+ if len(args) <= 1:
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
+
+ if "changeto" in command_string:
+ self.set_base_prompt()
+
+ return output
+
+
+
+def send_command_timing(self, *args, **kwargs)
+
+-
+
If the ASA is in multi-context mode, then the base_prompt needs to be
+updated after each context change.
+
+Source code
+def send_command_timing(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ If the ASA is in multi-context mode, then the base_prompt needs to be
+ updated after each context change.
+ """
+ output = super().send_command_timing(*args, **kwargs)
+ if len(args) >= 1:
+ command_string = args[0]
+ else:
+ command_string = kwargs["command_string"]
+ if "changeto" in command_string:
+ self.set_base_prompt()
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """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:
+ self.asa_login()
+ self.disable_paging(command="terminal pager 0")
+
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+
+
+def set_base_prompt(self, *args, **kwargs)
+
+-
+
Cisco ASA in multi-context mode needs to have the base prompt updated
+(if you switch contexts i.e. 'changeto')
+This switch of ASA contexts can occur in configuration mode. If this
+happens the trailing '(config*' needs stripped off.
+
+Source code
+def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Cisco ASA in multi-context mode needs to have the base prompt updated
+ (if you switch contexts i.e. 'changeto')
+
+ This switch of ASA contexts can occur in configuration mode. If this
+ happens the trailing '(config*' needs stripped off.
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
+ if match:
+ # strip off (conf.* from base_prompt
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return cur_base_prompt
+
+
+
+Inherited members
+
+
+
+class CiscoFtdSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Subclass specific to Cisco FTD.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoFtdSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Subclass specific to Cisco FTD."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
Canot change config on FTD via ssh
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
+
+
+
+def send_config_set(self, *args, **kwargs)
+
+-
+
Canot change config on FTD via ssh
+
+Source code
+def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class CiscoIosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Common Methods for IOS (both SSH and telnet).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosBase(CiscoBaseConnection):
+ """Common Methods for IOS (both SSH and telnet)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = r"#") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write mem', confirm=False, confirm_response='')
+
+-
+
Saves Config Using Copy Run Start
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config Using Copy Run Start"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
+ self.disable_paging()
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class CiscoIosFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco IOS SCP File Transfer driver.
+
+Source code
+class CiscoIosFileTransfer(CiscoFileTransfer):
+ """Cisco IOS SCP File Transfer driver."""
+
+ pass
+
+Ancestors
+
+Subclasses
+
+Inherited members
+
+
+
+class CiscoIosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosSSH(CiscoIosBase):
+ """Cisco IOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoIosSerial
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS Serial driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosSerial(CiscoIosBase):
+ """Cisco IOS Serial driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoIosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco IOS Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoIosTelnet(CiscoIosBase):
+ """Cisco IOS Telnet driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoNxosFileTransfer
+(ssh_conn, source_file, dest_file, file_system='bootflash:', direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco NXOS SCP File Transfer driver.
+
+Source code
+class CiscoNxosFileTransfer(CiscoFileTransfer):
+ """Cisco NXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: str = "bootflash:",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for NX-OS")
+
+ if file_system:
+ self.file_system = file_system
+ else:
+ raise ValueError("Destination file system must be specified for NX-OS")
+
+ if direction == "put":
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif direction == "get":
+ self.source_md5 = self.remote_md5(remote_file=source_file)
+ self.file_size = self.remote_file_size(remote_file=source_file)
+ else:
+ raise ValueError("Invalid direction specified")
+
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"{}.*Usage for".format(self.dest_file)
+ if "No such file or directory" in remote_out:
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
+
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if re.search("no such file or directory", remote_out, flags=re.I):
+ raise IOError("Unable to find file on remote system")
+ # Match line containing file name
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ file_size = match.group(0)
+ file_size = file_size.split()[0]
+ return int(file_size)
+
+ raise IOError("Unable to find file on remote system")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
+ """Not needed on NX-OS."""
+ raise NotImplementedError
+
+ def remote_md5(
+ self, base_cmd: str = "show file", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}{remote_file} md5sum"
+ output = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ output = output.strip()
+ return output
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Static methods
+
+
+def process_md5(md5_output, pattern='= (.*)')
+
+-
+
+
+Source code
+@staticmethod
+def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
+ """Not needed on NX-OS."""
+ raise NotImplementedError
+
+
+
+Inherited members
+
+
+
+class CiscoNxosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoNxosSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
+ self.disable_paging()
+ self.set_base_prompt()
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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|\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: str = ")#", pattern: str = "#") -> bool:
+ """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: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # NX-OS is very slow on save_config ensure it waits long enough.
+ output += self._send_command_str(
+ command_string=cmd,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=100,
+ )
+ 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: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Convert '
+' or '
+' to '
+, and remove extra '
+'s in the text.
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """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|\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 session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
+ self.disable_paging()
+ self.set_base_prompt()
+
+
+
+Inherited members
+
+
+
+class CiscoS300SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Cisco SG300 series of devices.
+Note, must configure the following to disable SG300 from prompting for username twice:
+configure terminal
+ip ssh password-auth
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoS300SSH(CiscoS300Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoS300Telnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Cisco SG300 series of devices, with telnet.
+Note: can be used with Sx200 series, with telnet enabled.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoS300Telnet(CiscoS300Base):
+ """
+ Support for Cisco SG300 series of devices, with telnet.
+ Note: can be used with Sx200 series, with telnet enabled.
+ """
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoTpTcCeSSH
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoTpTcCeSSH(CiscoSSHConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Paging is disabled by default."""
+ return ""
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some of vagaries that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self.set_base_prompt()
+ self.disable_paging()
+ self.set_terminal_width()
+ """
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as base_prompt."""
+ self.base_prompt = "OK"
+ return self.base_prompt
+
+ def find_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as standard prompt."""
+ return "OK"
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+ if re.search(expect_string, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Send command to network device retrieve output until router_prompt or expect_string
+
+ By default this method will keep waiting to receive data until the network device prompt is
+ detected. The current network device prompt will be determined automatically.
+ """
+ if len(args) >= 2:
+ expect_string = args[1]
+ else:
+ expect_string = kwargs.get("expect_string")
+ if expect_string is None:
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
+ expect_string = self.RETURN + expect_string + self.RETURN
+ kwargs.setdefault("expect_string", expect_string)
+
+ output = super().send_command(*args, **kwargs)
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Paging is disabled by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Paging is disabled by default."""
+ return ""
+
+
+
+def find_prompt(self, *args, **kwargs)
+
+-
+
Use 'OK' as standard prompt.
+
+Source code
+def find_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as standard prompt."""
+ return "OK"
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_command(self, *args, **kwargs)
+
+-
+
Send command to network device retrieve output until router_prompt or expect_string
+By default this method will keep waiting to receive data until the network device prompt is
+detected. The current network device prompt will be determined automatically.
+
+Source code
+def send_command(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Send command to network device retrieve output until router_prompt or expect_string
+
+ By default this method will keep waiting to receive data until the network device prompt is
+ detected. The current network device prompt will be determined automatically.
+ """
+ if len(args) >= 2:
+ expect_string = args[1]
+ else:
+ expect_string = kwargs.get("expect_string")
+ if expect_string is None:
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
+ expect_string = self.RETURN + expect_string + self.RETURN
+ kwargs.setdefault("expect_string", expect_string)
+
+ output = super().send_command(*args, **kwargs)
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+This method handles some of vagaries that occur between various devices
+early on in the session.
+In general, it should include:
+self.set_base_prompt()
+self.disable_paging()
+self.set_terminal_width()
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some of vagaries that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self.set_base_prompt()
+ self.disable_paging()
+ self.set_terminal_width()
+ """
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, *args, **kwargs)
+
+-
+
+
+Source code
+def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Use 'OK' as base_prompt."""
+ self.base_prompt = "OK"
+ return self.base_prompt
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+ if re.search(expect_string, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+
+
+Inherited members
+
+
+
+class CiscoViptelaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Subclass specific to Cisco Viptela.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoViptelaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco Viptela."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def commit(self, confirm: bool = False, confirm_response: str = "") -> str:
+ cmd = "commit"
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def config_mode(
+ self,
+ config_command: str = "conf terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ raise NotImplementedError
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def exit_config_mode(self, exit_config='end', pattern='#')
+
+-
+
Exit from configuration mode.
+Viptela might have the following in the output (if no 'commit()' occurred.
+Uncommitted changes found, commit them? [yes/no/CANCEL]
+
+Source code
+def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+
+
+def save_config(self, cmd='commit', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+
+
+Inherited members
+
+
+
+class CiscoWlcSSH
+(*args, **kwargs)
+
+-
+
Netmiko Cisco WLC support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoWlcSSH(BaseConnection):
+ """Netmiko Cisco WLC support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ # WLC/AireOS has an issue where you can get "No Existing Session" with
+ # the default conn_timeout (so increase conn_timeout to 10-seconds).
+ kwargs.setdefault("conn_timeout", 10)
+ return super().__init__(*args, **kwargs)
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """WLC presents with the following on login (in certain OS versions)
+
+ login as: user
+
+ (Cisco Controller)
+
+ User: user
+
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ # no output read, sleep and go for one more round of read channel
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+ def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
+ Even though pagination is disabled
+ show run-config also has excessive delays in the output which requires special
+ handling.
+ Arguments are the same as send_command_timing() method
+ """
+ if len(args) > 1:
+ raise ValueError("Must pass in delay_factor as keyword argument")
+
+ # If no delay_factor use 1 for default value
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
+
+ if "Press any key" in output or "Press Enter to" in output:
+ new_args = list(args)
+ if len(args) == 1:
+ new_args[0] = self.RETURN
+ else:
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
+
+ # Send an 'enter'
+ output += self._send_command_timing_str(*new_args, **kwargs)
+
+ # WLC has excessive delay after this appears on screen
+ if "802.11b Advanced Configuration" in output:
+
+ # Defaults to 30 seconds
+ time.sleep(kwargs["delay_factor"] * 30)
+ not_done = True
+ i = 1
+ while not_done and i <= 150:
+ time.sleep(kwargs["delay_factor"] * 3)
+ i += 1
+ new_data = ""
+ new_data = self.read_channel()
+ if new_data:
+ output += new_data
+ else:
+ not_done = False
+
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ Cisco WLC uses "config paging disable" to disable paging
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ self.disable_paging(command="config paging disable")
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
+ self.send_command_timing("config paging enable")
+
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+ def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+ ) -> bool:
+ """Checks if the device is in configuration mode or not."""
+ if not pattern:
+ pattern = re.escape(self.base_prompt)
+ return super().check_config_mode(check_string, pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit config_mode."""
+ return super().exit_config_mode(exit_config, pattern)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs,
+ )
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='config', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+
+Source code
+def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+) -> bool:
+ """Checks if the device is in configuration mode or not."""
+ if not pattern:
+ pattern = re.escape(self.base_prompt)
+ return super().check_config_mode(check_string, pattern)
+
+
+
+def cleanup(self, command='logout')
+
+-
+
Reset WLC back to normal paging and gracefully close session.
+
+Source code
+def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
+ self.send_command_timing("config paging enable")
+
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+
+
+def config_mode(self, config_command='config', pattern='', re_flags=0)
+
+-
+
+
+Source code
+def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter into config_mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit config_mode."""
+ return super().exit_config_mode(exit_config, pattern)
+
+
+
+def save_config(self, cmd='save config', confirm=True, confirm_response='y')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+
+
+def send_command_w_enter(self, *args, **kwargs)
+
+-
+
For 'show run-config' Cisco WLC adds a 'Press Enter to continue…' message
+Even though pagination is disabled
+show run-config also has excessive delays in the output which requires special
+handling.
+Arguments are the same as send_command_timing() method
+
+Source code
+def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
+ Even though pagination is disabled
+ show run-config also has excessive delays in the output which requires special
+ handling.
+ Arguments are the same as send_command_timing() method
+ """
+ if len(args) > 1:
+ raise ValueError("Must pass in delay_factor as keyword argument")
+
+ # If no delay_factor use 1 for default value
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
+
+ if "Press any key" in output or "Press Enter to" in output:
+ new_args = list(args)
+ if len(args) == 1:
+ new_args[0] = self.RETURN
+ else:
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
+
+ # Send an 'enter'
+ output += self._send_command_timing_str(*new_args, **kwargs)
+
+ # WLC has excessive delay after this appears on screen
+ if "802.11b Advanced Configuration" in output:
+
+ # Defaults to 30 seconds
+ time.sleep(kwargs["delay_factor"] * 30)
+ not_done = True
+ i = 1
+ while not_done and i <= 150:
+ time.sleep(kwargs["delay_factor"] * 3)
+ i += 1
+ new_data = ""
+ new_data = self.read_channel()
+ if new_data:
+ output += new_data
+ else:
+ not_done = False
+
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+
+
+def send_command_w_yes(self, *args, **kwargs)
+
+-
+
For 'show interface summary' Cisco WLC adds a
+'Would you like to display the next 15 entries?' message
+Even though pagination is disabled
+Arguments are the same as send_command_timing() method
+
+Source code
+def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+Cisco WLC uses "config paging disable" to disable paging
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ Cisco WLC uses "config paging disable" to disable paging
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ self.disable_paging(command="config paging disable")
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
WLC presents with the following on login (in certain OS versions)
+login as: user
+(Cisco Controller)
+User: user
+Password:****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """WLC presents with the following on login (in certain OS versions)
+
+ login as: user
+
+ (Cisco Controller)
+
+ User: user
+
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ # no output read, sleep and go for one more round of read channel
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class CiscoXrFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Cisco IOS-XR SCP File Transfer driver.
+
+Source code
+class CiscoXrFileTransfer(CiscoFileTransfer):
+ """Cisco IOS-XR SCP File Transfer driver."""
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
+ """
+ IOS-XR defaults with timestamps enabled
+
+ # show md5 file /bootflash:/boot/grub/grub.cfg
+ Sat Mar 3 17:49:03.596 UTC
+ c84843f0030efd44b01343fdb8c2e801
+ """
+ match = re.search(pattern, md5_output, flags=re.M)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+ def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+ ) -> str:
+ """
+ IOS-XR for MD5 requires this extra leading /
+
+ show md5 file /bootflash:/boot/grub/grub.cfg
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ # IOS-XR requires both the leading slash and the slash between file-system and file here
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Static methods
+
+
+def process_md5(md5_output, pattern='^([a-fA-F0-9]+)$')
+
+-
+
IOS-XR defaults with timestamps enabled
+show md5 file /bootflash:/boot/grub/grub.cfg
+Sat Mar
+3 17:49:03.596 UTC
+c84843f0030efd44b01343fdb8c2e801
+
+Source code
+@staticmethod
+def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
+ """
+ IOS-XR defaults with timestamps enabled
+
+ # show md5 file /bootflash:/boot/grub/grub.cfg
+ Sat Mar 3 17:49:03.596 UTC
+ c84843f0030efd44b01343fdb8c2e801
+ """
+ match = re.search(pattern, md5_output, flags=re.M)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+
+
+Methods
+
+
+def remote_md5(self, base_cmd='show md5 file', remote_file=None)
+
+-
+
IOS-XR for MD5 requires this extra leading /
+show md5 file /bootflash:/boot/grub/grub.cfg
+
+Source code
+def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+) -> str:
+ """
+ IOS-XR for MD5 requires this extra leading /
+
+ show md5 file /bootflash:/boot/grub/grub.cfg
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ # IOS-XR requires both the leading slash and the slash between file-system and file here
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+
+
+Inherited members
+
+
+
+-
+
Cisco XR SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoXrSSH(CiscoXrBase):
+ """Cisco XR SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class CiscoXrTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Cisco XR Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoXrTelnet(CiscoXrBase):
+ """Cisco XR Telnet driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class InLineTransfer
+(ssh_conn, source_file='', dest_file='', file_system=None, direction='put', source_config=None, socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Use TCL on Cisco IOS to directly transfer file.
+
+Source code
+class InLineTransfer(CiscoIosFileTransfer):
+ """Use TCL on Cisco IOS to directly transfer file."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str = "",
+ dest_file: str = "",
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ source_config: Optional[str] = None,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+
+ if not dest_file:
+ raise ValueError(
+ "Destination file must be specified for InlineTransfer operations."
+ )
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for InLineTransfer")
+
+ if source_file and source_config:
+ msg = "Invalid call to InLineTransfer both source_file and source_config specified."
+ raise ValueError(msg)
+ if direction != "put":
+ raise ValueError("Only put operation supported by InLineTransfer.")
+
+ if progress is not None or progress4 is not None:
+ raise NotImplementedError(
+ "Progress bar is not supported on inline transfers."
+ )
+ else:
+ self.progress = progress
+ self.progress4 = progress4
+
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ if source_file:
+ self.source_config = None
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif source_config:
+ self.source_config = source_config
+ self.source_md5 = self.config_md5(source_config)
+ self.file_size = len(source_config.encode("UTF-8"))
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if not file_system:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ self.file_system = file_system
+
+ self.socket_timeout = socket_timeout
+
+ @staticmethod
+ def _read_file(file_name: str) -> str:
+ with io.open(file_name, "rt", encoding="utf-8") as f:
+ return f.read()
+
+ @staticmethod
+ def _tcl_newline_rationalize(tcl_string: str) -> str:
+ r"""
+ When using put inside a TCL {} section the newline is considered a new TCL
+ statement and causes a missing curly-brace message. Convert "\n" to "\r". TCL
+ will convert the "\r" to a "\n" i.e. you will see a "\n" inside the file on the
+ Cisco IOS device.
+ """
+ NEWLINE = r"\n"
+ CARRIAGE_RETURN = r"\r"
+ tmp_string = re.sub(NEWLINE, CARRIAGE_RETURN, tcl_string)
+ if re.search(r"[{}]", tmp_string):
+ msg = "Curly brace detected in string; TCL requires this be escaped."
+ raise ValueError(msg)
+ return tmp_string
+
+ def __enter__(self) -> "InLineTransfer":
+ self._enter_tcl_mode()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ self._exit_tcl_mode()
+
+ def _enter_tcl_mode(self) -> str:
+ TCL_ENTER = "tclsh"
+ cmd_failed = ['Translating "tclsh"', "% Unknown command", "% Bad IP address"]
+ output = self.ssh_ctl_chan._send_command_str(
+ TCL_ENTER,
+ expect_string=r"\(tcl\)#",
+ strip_prompt=False,
+ strip_command=False,
+ )
+ for pattern in cmd_failed:
+ if pattern in output:
+ raise ValueError(f"Failed to enter tclsh mode on router: {output}")
+ return output
+
+ def _exit_tcl_mode(self) -> str:
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel("\r")
+ time.sleep(1)
+ output = self.ssh_ctl_chan.read_channel()
+ if "(tcl)" in output:
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+ time.sleep(1)
+ output += self.ssh_ctl_chan.read_channel()
+ return output
+
+ def establish_scp_conn(self) -> None:
+ raise NotImplementedError
+
+ def close_scp_chan(self) -> None:
+ raise NotImplementedError
+
+ def local_space_available(self) -> bool:
+ raise NotImplementedError
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def put_file(self) -> None:
+ curlybrace = r"{"
+ TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(
+ self.file_system, self.dest_file, curlybrace
+ )
+ TCL_FILECMD_EXIT = "}"
+
+ if self.source_file:
+ file_contents = self._read_file(self.source_file)
+ elif self.source_config:
+ file_contents = self.source_config
+ file_contents = self._tcl_newline_rationalize(file_contents)
+
+ # Try to remove any existing data
+ self.ssh_ctl_chan.clear_buffer()
+
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_ENTER)
+ time.sleep(0.25)
+ self.ssh_ctl_chan.write_channel(file_contents)
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_EXIT + "\r")
+
+ # This operation can be slow (depends on the size of the file)
+ read_timeout = 100
+ sleep_time = 4
+ if self.file_size >= 2500:
+ read_timeout = 300
+ sleep_time = 12
+ elif self.file_size >= 7500:
+ read_timeout = 600
+ sleep_time = 25
+
+ # Initial delay
+ time.sleep(sleep_time)
+
+ # File paste and TCL_FILECMD_exit should be indicated by "router(tcl)#"
+ output = self.ssh_ctl_chan.read_until_pattern(
+ pattern=r"\(tcl\).*$", re_flags=re.M, read_timeout=read_timeout
+ )
+
+ # The file doesn't write until tclquit
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+
+ time.sleep(1)
+ # Read all data remaining from the TCLSH session
+ pattern = rf"tclquit.*{self.ssh_ctl_chan.base_prompt}.*$"
+ re_flags = re.DOTALL | re.M
+ output += self.ssh_ctl_chan.read_until_pattern(
+ pattern=pattern, re_flags=re_flags, read_timeout=read_timeout
+ )
+ return None
+
+ def get_file(self) -> None:
+ raise NotImplementedError
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def config_md5(self, source_config)
+
+-
+
Compute MD5 hash of text.
+
+Source code
+def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+def file_md5(self, file_name, add_newline=False)
+
+-
+
Compute MD5 hash of file.
+
+Source code
+def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html
new file mode 100644
index 000000000..c16efae55
--- /dev/null
+++ b/docs/netmiko/cisco_base_connection.html
@@ -0,0 +1,1326 @@
+
+
+
+
+
+
+netmiko.cisco_base_connection API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cisco_base_connection
+
+
+CiscoBaseConnection is netmiko SSH class for Cisco and Cisco-like platforms.
+
+Source code
+"""CiscoBaseConnection is netmiko SSH class for Cisco and Cisco-like platforms."""
+from typing import Optional
+import re
+import time
+from netmiko.base_connection import BaseConnection
+from netmiko.scp_handler import BaseFileTransfer
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class CiscoBaseConnection(BaseConnection):
+ """Base Class for cisco-like behavior."""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ """Exits enable (privileged exec) mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#.*") -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ self.write_channel(self.TELNET_RETURN)
+ output = self.read_channel()
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return output
+ else:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login. Can be username/password or just password."""
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ outer_loops = 3
+ inner_loops = int(max_loops / outer_loops)
+ i = 1
+ for _ in range(outer_loops):
+ while i <= inner_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Support direct telnet through terminal server
+ if re.search(
+ r"initial configuration dialog\? \[yes/no\]: ", output
+ ):
+ self.write_channel("no" + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ count = 0
+ while count < 15:
+ output = self.read_channel()
+ return_msg += output
+ if re.search(r"ress RETURN to get started", output):
+ output = ""
+ break
+ time.sleep(2 * delay_factor)
+ count += 1
+
+ # Check for device with no password configured
+ if re.search(r"assword required, but none set", output):
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = (
+ "Login failed - Password required, but none set: {}".format(
+ self.host
+ )
+ )
+ raise NetmikoAuthenticationException(msg)
+
+ # Check if proper data received
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Try sending an <enter> to restart the login process
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i = 1
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ if self.session_log:
+ self.session_log.fin = True
+ self.write_channel(command + self.RETURN)
+
+ def _autodetect_fs(
+ self, cmd: str = "dir", pattern: str = r"Directory of (.*)/"
+ ) -> str:
+ """Autodetect the file system on the remote device. Used by SCP operations."""
+ if not self.check_enable_mode():
+ raise ValueError("Must be in enable mode to auto-detect the file-system.")
+ output = self._send_command_str(cmd)
+ match = re.search(pattern, output)
+ if match:
+ file_system = match.group(1)
+ # Test file_system
+ cmd = f"dir {file_system}"
+ output = self._send_command_str(cmd)
+ if "% Invalid" in output or "%Error:" in output:
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
+ else:
+ return file_system
+
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+
+class CiscoSSHConnection(CiscoBaseConnection):
+ pass
+
+
+class CiscoFileTransfer(BaseFileTransfer):
+ pass
+
+
+
+
+
+
+
+
+
+class CiscoBaseConnection
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoBaseConnection(BaseConnection):
+ """Base Class for cisco-like behavior."""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ """Exits enable (privileged exec) mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#.*") -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ self.write_channel(self.TELNET_RETURN)
+ output = self.read_channel()
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return output
+ else:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login. Can be username/password or just password."""
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ outer_loops = 3
+ inner_loops = int(max_loops / outer_loops)
+ i = 1
+ for _ in range(outer_loops):
+ while i <= inner_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Support direct telnet through terminal server
+ if re.search(
+ r"initial configuration dialog\? \[yes/no\]: ", output
+ ):
+ self.write_channel("no" + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ count = 0
+ while count < 15:
+ output = self.read_channel()
+ return_msg += output
+ if re.search(r"ress RETURN to get started", output):
+ output = ""
+ break
+ time.sleep(2 * delay_factor)
+ count += 1
+
+ # Check for device with no password configured
+ if re.search(r"assword required, but none set", output):
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = (
+ "Login failed - Password required, but none set: {}".format(
+ self.host
+ )
+ )
+ raise NetmikoAuthenticationException(msg)
+
+ # Check if proper data received
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Try sending an <enter> to restart the login process
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i = 1
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ if self.session_log:
+ self.session_log.fin = True
+ self.write_channel(command + self.RETURN)
+
+ def _autodetect_fs(
+ self, cmd: str = "dir", pattern: str = r"Directory of (.*)/"
+ ) -> str:
+ """Autodetect the file system on the remote device. Used by SCP operations."""
+ if not self.check_enable_mode():
+ raise ValueError("Must be in enable mode to auto-detect the file-system.")
+ output = self._send_command_str(cmd)
+ match = re.search(pattern, output)
+ if match:
+ file_system = match.group(1)
+ # Test file_system
+ cmd = f"dir {file_system}"
+ output = self._send_command_str(cmd)
+ if "% Invalid" in output or "%Error:" in output:
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
+ else:
+ return file_system
+
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=')#', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+
+Source code
+def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ 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: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+
+
+def cleanup(self, command='exit')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ if self.session_log:
+ self.session_log.fin = True
+ self.write_channel(command + self.RETURN)
+
+
+
+def enable(self, cmd='enable', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter enable mode."""
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='end', pattern='#.*')
+
+-
+
Exit from configuration mode.
+
+Source code
+def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#.*") -> str:
+ """Exit from configuration 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: str = "disable") -> str:
+ """Exits enable (privileged exec) mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+
+
+def serial_login(self, pri_prompt_terminator='\\#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:user:|username|login)', pwd_pattern='assword', delay_factor=1.0, max_loops=20)
+
+-
+
+
+Source code
+def serial_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ self.write_channel(self.TELNET_RETURN)
+ output = self.read_channel()
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return output
+ else:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+
+
+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.0, max_loops=20)
+
+-
+
Telnet login. Can be username/password or just password.
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """Telnet login. Can be username/password or just password."""
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ outer_loops = 3
+ inner_loops = int(max_loops / outer_loops)
+ i = 1
+ for _ in range(outer_loops):
+ while i <= inner_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Support direct telnet through terminal server
+ if re.search(
+ r"initial configuration dialog\? \[yes/no\]: ", output
+ ):
+ self.write_channel("no" + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ count = 0
+ while count < 15:
+ output = self.read_channel()
+ return_msg += output
+ if re.search(r"ress RETURN to get started", output):
+ output = ""
+ break
+ time.sleep(2 * delay_factor)
+ count += 1
+
+ # Check for device with no password configured
+ if re.search(r"assword required, but none set", output):
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = (
+ "Login failed - Password required, but none set: {}".format(
+ self.host
+ )
+ )
+ raise NetmikoAuthenticationException(msg)
+
+ # Check if proper data received
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Try sending an <enter> to restart the login process
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i = 1
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+
+
+Inherited members
+
+
+
+class CiscoFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Class to manage SCP file transfer and associated SSH control channel.
+
+Source code
+class CiscoFileTransfer(BaseFileTransfer):
+ pass
+
+Ancestors
+
+Subclasses
+
+Inherited members
+
+
+
+class CiscoSSHConnection
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CiscoSSHConnection(CiscoBaseConnection):
+ pass
+
+Ancestors
+
+Subclasses
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/citrix/index.html b/docs/netmiko/citrix/index.html
new file mode 100644
index 000000000..c2cbea3b2
--- /dev/null
+++ b/docs/netmiko/citrix/index.html
@@ -0,0 +1,357 @@
+
+
+
+
+
+
+netmiko.citrix API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.citrix.netscaler_ssh import NetscalerSSH
+
+__all__ = ["NetscalerSSH"]
+
+
+
+
+
+
+
+
+
+-
+
Netscaler SSH class.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetscalerSSH(NoConfig, BaseConnection):
+ """Netscaler SSH class."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
+ self.disable_paging(command=cmd)
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt.
+
+ Netscaler has only '>' for the prompt.
+ """
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
+ return self.base_prompt
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
+ lines = output.split(self.RESPONSE_RETURN)
+ if "Done" in lines[-1]:
+ return self.RESPONSE_RETURN.join(lines[:-1])
+ else:
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
+ self.disable_paging(command=cmd)
+ self.set_base_prompt()
+
+
+
+-
+
Sets self.base_prompt.
+Netscaler has only '>' for the prompt.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt.
+
+ Netscaler has only '>' for the prompt.
+ """
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
+ return self.base_prompt
+
+
+
+-
+
Strip 'Done' from command output
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
+ lines = output.split(self.RESPONSE_RETURN)
+ if "Done" in lines[-1]:
+ return self.RESPONSE_RETURN.join(lines[:-1])
+ else:
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/citrix/netscaler_ssh.html b/docs/netmiko/citrix/netscaler_ssh.html
new file mode 100644
index 000000000..9560e20ee
--- /dev/null
+++ b/docs/netmiko/citrix/netscaler_ssh.html
@@ -0,0 +1,388 @@
+
+
+
+
+
+
+netmiko.citrix.netscaler_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.citrix.netscaler_ssh
+
+
+
+Source code
+from typing import Optional
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class NetscalerSSH(NoConfig, BaseConnection):
+ """Netscaler SSH class."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
+ self.disable_paging(command=cmd)
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt.
+
+ Netscaler has only '>' for the prompt.
+ """
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
+ return self.base_prompt
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
+ lines = output.split(self.RESPONSE_RETURN)
+ if "Done" in lines[-1]:
+ return self.RESPONSE_RETURN.join(lines[:-1])
+ else:
+ return output
+
+
+
+
+
+
+
+
+
+-
+
Netscaler SSH class.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetscalerSSH(NoConfig, BaseConnection):
+ """Netscaler SSH class."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
+ self.disable_paging(command=cmd)
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt.
+
+ Netscaler has only '>' for the prompt.
+ """
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
+ return self.base_prompt
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
+ lines = output.split(self.RESPONSE_RETURN)
+ if "Done" in lines[-1]:
+ return self.RESPONSE_RETURN.join(lines[:-1])
+ else:
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
+ self.disable_paging(command=cmd)
+ self.set_base_prompt()
+
+
+
+-
+
Sets self.base_prompt.
+Netscaler has only '>' for the prompt.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt.
+
+ Netscaler has only '>' for the prompt.
+ """
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
+ return self.base_prompt
+
+
+
+-
+
Strip 'Done' from command output
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
+ lines = output.split(self.RESPONSE_RETURN)
+ if "Done" in lines[-1]:
+ return self.RESPONSE_RETURN.join(lines[:-1])
+ else:
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cli_tools/index.html b/docs/netmiko/cli_tools/index.html
new file mode 100644
index 000000000..94f2785c8
--- /dev/null
+++ b/docs/netmiko/cli_tools/index.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+netmiko.cli_tools API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cli_tools
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cli_tools/netmiko_cfg.html b/docs/netmiko/cli_tools/netmiko_cfg.html
new file mode 100644
index 000000000..b7ed0ee13
--- /dev/null
+++ b/docs/netmiko/cli_tools/netmiko_cfg.html
@@ -0,0 +1,521 @@
+
+
+
+
+
+
+netmiko.cli_tools.netmiko_cfg API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cli_tools.netmiko_cfg
+
+
+Return output from single show cmd using Netmiko.
+
+Source code
+#!/usr/bin/env python
+"""Return output from single show cmd using Netmiko."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+PY2 = sys.version_info.major == 2
+PY3 = sys.version_info.major == 3
+
+if sys.version_info.major == 3:
+ string_types = (str,)
+ text_type = str
+else:
+ string_types = (basestring,) # noqa
+ text_type = unicode # noqa
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cfg_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ if isinstance(cfg_command, string_types):
+ cfg_command = [cfg_command]
+ output = net_connect.send_config_set(cfg_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Execute single config cmd using Netmiko"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--infile", help="Read commands from file", type=argparse.FileType("r")
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Config command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ if not cli_args.cmd and not cli_args.infile:
+ parser.error("No configuration commands provided.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-cfg v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ if r"\n" in cli_command:
+ cli_command = cli_command.strip()
+ cli_command = cli_command.split(r"\n")
+ elif input:
+ cmd_arg = True
+ command_data = cli_args.infile.read()
+ command_data = command_data.strip()
+ cli_command = command_data.splitlines()
+ else:
+ raise ValueError("No configuration commands provided.")
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
+
+
+
+
+
+
+
+
+def grepx(files, pattern, grep_options, use_colors=True)
+
+-
+
+
+Source code
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+
+def main(args)
+
+-
+
+
+Source code
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-cfg v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ if r"\n" in cli_command:
+ cli_command = cli_command.strip()
+ cli_command = cli_command.split(r"\n")
+ elif input:
+ cmd_arg = True
+ command_data = cli_args.infile.read()
+ command_data = command_data.strip()
+ cli_command = command_data.splitlines()
+ else:
+ raise ValueError("No configuration commands provided.")
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+
+def main_ep()
+
+-
+
+
+Source code
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+
+def parse_arguments(args)
+
+-
+
Parse command-line arguments.
+
+Source code
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Execute single config cmd using Netmiko"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--infile", help="Read commands from file", type=argparse.FileType("r")
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Config command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ if not cli_args.cmd and not cli_args.infile:
+ parser.error("No configuration commands provided.")
+ return cli_args
+
+
+
+def ssh_conn(device_name, a_device, cfg_command, output_q)
+
+-
+
+
+Source code
+def ssh_conn(device_name, a_device, cfg_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ if isinstance(cfg_command, string_types):
+ cfg_command = [cfg_command]
+ output = net_connect.send_config_set(cfg_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cli_tools/netmiko_grep.html b/docs/netmiko/cli_tools/netmiko_grep.html
new file mode 100644
index 000000000..b4124e155
--- /dev/null
+++ b/docs/netmiko/cli_tools/netmiko_grep.html
@@ -0,0 +1,513 @@
+
+
+
+
+
+
+netmiko.cli_tools.netmiko_grep API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cli_tools.netmiko_grep
+
+
+Create grep like remote behavior on show run or command output.
+
+Source code
+#!/usr/bin/env python
+"""Create grep like remote behavior on show run or command output."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import obtain_netmiko_filename, write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Grep pattern search on Netmiko output (defaults to running-config)"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "pattern", nargs="?", help="Pattern to search for", action="store", type=str
+ )
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices or not cli_args.pattern:
+ parser.error("Grep pattern or devices not specified.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-grep v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = cli_args.pattern
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
+
+
+
+
+
+
+
+
+def grepx(files, pattern, grep_options, use_colors=True)
+
+-
+
+
+Source code
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+
+def main(args)
+
+-
+
+
+Source code
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-grep v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = cli_args.pattern
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+
+def main_ep()
+
+-
+
+
+Source code
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+
+def parse_arguments(args)
+
+-
+
Parse command-line arguments.
+
+Source code
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Grep pattern search on Netmiko output (defaults to running-config)"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "pattern", nargs="?", help="Pattern to search for", action="store", type=str
+ )
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices or not cli_args.pattern:
+ parser.error("Grep pattern or devices not specified.")
+ return cli_args
+
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q)
+
+-
+
+
+Source code
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cli_tools/netmiko_show.html b/docs/netmiko/cli_tools/netmiko_show.html
new file mode 100644
index 000000000..ed1299e5a
--- /dev/null
+++ b/docs/netmiko/cli_tools/netmiko_show.html
@@ -0,0 +1,511 @@
+
+
+
+
+
+
+netmiko.cli_tools.netmiko_show API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cli_tools.netmiko_show
+
+
+Return output from single show cmd using Netmiko.
+
+Source code
+#!/usr/bin/env python
+"""Return output from single show cmd using Netmiko."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import obtain_netmiko_filename, write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = (
+ "Return output from single show cmd using Netmiko (defaults to running-config)"
+ )
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-show v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
+
+
+
+
+
+
+
+
+def grepx(files, pattern, grep_options, use_colors=True)
+
+-
+
+
+Source code
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+
+def main(args)
+
+-
+
+
+Source code
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-show v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+
+def main_ep()
+
+-
+
+
+Source code
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+
+def parse_arguments(args)
+
+-
+
Parse command-line arguments.
+
+Source code
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = (
+ "Return output from single show cmd using Netmiko (defaults to running-config)"
+ )
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ return cli_args
+
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q)
+
+-
+
+
+Source code
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cloudgenix/cloudgenix_ion.html b/docs/netmiko/cloudgenix/cloudgenix_ion.html
new file mode 100644
index 000000000..681e7d7f3
--- /dev/null
+++ b/docs/netmiko/cloudgenix/cloudgenix_ion.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+netmiko.cloudgenix.cloudgenix_ion API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cloudgenix.cloudgenix_ion
+
+
+
+Source code
+from typing import Any, Union, Sequence, TextIO, Optional
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CloudGenixIonSSH(NoConfig, CiscoSSHConnection):
+ def establish_connection(self, width: int = 100, height: int = 1000) -> None:
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ prompt = super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+ prompt = self.strip_backspaces(prompt).strip()
+ return prompt
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ output = super().strip_command(command_string, output)
+ # command_string gets repainted potentially multiple times (grab everything after last one)
+ output = output.split(command_string)[-1]
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+
+
+
+
+
+
+
+
+class CloudGenixIonSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CloudGenixIonSSH(NoConfig, CiscoSSHConnection):
+ def establish_connection(self, width: int = 100, height: int = 1000) -> None:
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ prompt = super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+ prompt = self.strip_backspaces(prompt).strip()
+ return prompt
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ output = super().strip_command(command_string, output)
+ # command_string gets repainted potentially multiple times (grab everything after last one)
+ output = output.split(command_string)[-1]
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Cloud Genix ION sets terminal height in establish_connection
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self, *args, **kwargs)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/cloudgenix/index.html b/docs/netmiko/cloudgenix/index.html
new file mode 100644
index 000000000..1147f698c
--- /dev/null
+++ b/docs/netmiko/cloudgenix/index.html
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+netmiko.cloudgenix API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.cloudgenix
+
+
+
+Source code
+from netmiko.cloudgenix.cloudgenix_ion import CloudGenixIonSSH
+
+__all__ = ["CloudGenixIonSSH"]
+
+
+
+
+
+
+
+
+
+class CloudGenixIonSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CloudGenixIonSSH(NoConfig, CiscoSSHConnection):
+ def establish_connection(self, width: int = 100, height: int = 1000) -> None:
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ prompt = super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+ prompt = self.strip_backspaces(prompt).strip()
+ return prompt
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ output = super().strip_command(command_string, output)
+ # command_string gets repainted potentially multiple times (grab everything after last one)
+ output = output.split(command_string)[-1]
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Cloud Genix ION sets terminal height in establish_connection
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self, *args, **kwargs)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/coriant/coriant_ssh.html b/docs/netmiko/coriant/coriant_ssh.html
new file mode 100644
index 000000000..40dc18d23
--- /dev/null
+++ b/docs/netmiko/coriant/coriant_ssh.html
@@ -0,0 +1,337 @@
+
+
+
+
+
+
+netmiko.coriant.coriant_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.coriant.coriant_ssh
+
+
+
+Source code
+from typing import Any, Optional
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CoriantSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>:]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class CoriantSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CoriantSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>:]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='>', delay_factor=2.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/coriant/index.html b/docs/netmiko/coriant/index.html
new file mode 100644
index 000000000..ab7dbcf15
--- /dev/null
+++ b/docs/netmiko/coriant/index.html
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+netmiko.coriant API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.coriant
+
+
+
+Source code
+from netmiko.coriant.coriant_ssh import CoriantSSH
+
+__all__ = ["CoriantSSH"]
+
+
+
+
+
+
+
+
+
+class CoriantSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class CoriantSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>:]")
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='>', delay_factor=2.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_dnos6.html b/docs/netmiko/dell/dell_dnos6.html
new file mode 100644
index 000000000..d1e575038
--- /dev/null
+++ b/docs/netmiko/dell/dell_dnos6.html
@@ -0,0 +1,661 @@
+
+
+
+
+
+
+netmiko.dell.dell_dnos6 API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_dnos6
+
+
+Dell N2/3/4000 base driver- supports DNOS6.
+
+Source code
+"""Dell N2/3/4000 base driver- supports DNOS6."""
+from netmiko.dell.dell_powerconnect import DellPowerConnectBase
+
+
+class DellDNOS6Base(DellPowerConnectBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class DellDNOS6SSH(DellDNOS6Base):
+ pass
+
+
+class DellDNOS6Telnet(DellDNOS6Base):
+ pass
+
+
+
+
+
+
+
+
+
+class DellDNOS6Base
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellDNOS6Base(DellPowerConnectBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class DellDNOS6SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellDNOS6SSH(DellDNOS6Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DellDNOS6Telnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellDNOS6Telnet(DellDNOS6Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_force10_ssh.html b/docs/netmiko/dell/dell_force10_ssh.html
new file mode 100644
index 000000000..b78262ad4
--- /dev/null
+++ b/docs/netmiko/dell/dell_force10_ssh.html
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+netmiko.dell.dell_force10_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_force10_ssh
+
+
+Dell Force10 Driver - supports DNOS9.
+
+Source code
+"""Dell Force10 Driver - supports DNOS9."""
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class DellForce10SSH(CiscoSSHConnection):
+ """Dell Force10 Driver - supports DNOS9."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class DellForce10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell Force10 Driver - supports DNOS9.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellForce10SSH(CiscoSSHConnection):
+ """Dell Force10 Driver - supports DNOS9."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_isilon_ssh.html b/docs/netmiko/dell/dell_isilon_ssh.html
new file mode 100644
index 000000000..97f892aa0
--- /dev/null
+++ b/docs/netmiko/dell/dell_isilon_ssh.html
@@ -0,0 +1,539 @@
+
+
+
+
+
+
+netmiko.dell.dell_isilon_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_isilon_ssh
+
+
+
+Source code
+from typing import Any, Optional
+import time
+import re
+
+from netmiko.base_connection import BaseConnection
+
+
+class DellIsilonSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+ def _zsh_mode(self, prompt_terminator: str = "$") -> None:
+ """Run zsh command to unify the environment"""
+ if self.global_delay_factor < 1:
+ delay_factor = 1.0
+ else:
+ delay_factor = self.global_delay_factor
+ command = self.RETURN + "zsh" + self.RETURN
+ self.write_channel(command)
+ time.sleep(0.25 * delay_factor)
+ self._set_prompt(prompt_terminator)
+ time.sleep(0.25 * delay_factor)
+ self.clear_buffer()
+
+ def _set_prompt(self, prompt_terminator: str = "$") -> None:
+ prompt = f"PROMPT='%m{prompt_terminator}'"
+ command = self.RETURN + prompt + self.RETURN
+ self.write_channel(command)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "sudo su",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ delay_factor = self.select_delay_factor(delay_factor=1)
+ output = ""
+ if not self.check_enable_mode():
+ output += self._send_command_timing_str(
+ cmd, strip_prompt=False, strip_command=False
+ )
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_pattern(pattern=r"#.*$")
+ time.sleep(1 * delay_factor)
+ self._set_prompt(prompt_terminator="#")
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode")
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
+
+
+
+
+
+
+
+
+
+class DellIsilonSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellIsilonSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+ def _zsh_mode(self, prompt_terminator: str = "$") -> None:
+ """Run zsh command to unify the environment"""
+ if self.global_delay_factor < 1:
+ delay_factor = 1.0
+ else:
+ delay_factor = self.global_delay_factor
+ command = self.RETURN + "zsh" + self.RETURN
+ self.write_channel(command)
+ time.sleep(0.25 * delay_factor)
+ self._set_prompt(prompt_terminator)
+ time.sleep(0.25 * delay_factor)
+ self.clear_buffer()
+
+ def _set_prompt(self, prompt_terminator: str = "$") -> None:
+ prompt = f"PROMPT='%m{prompt_terminator}'"
+ command = self.RETURN + prompt + self.RETURN
+ self.write_channel(command)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "sudo su",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ delay_factor = self.select_delay_factor(delay_factor=1)
+ output = ""
+ if not self.check_enable_mode():
+ output += self._send_command_timing_str(
+ cmd, strip_prompt=False, strip_command=False
+ )
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_pattern(pattern=r"#.*$")
+ time.sleep(1 * delay_factor)
+ self._set_prompt(prompt_terminator="#")
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode")
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Use equivalent enable method.
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+
+
+def config_mode(self, config_command='sudo su', pattern='ssword', re_flags=)
+
+-
+
Use equivalent enable method.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Isilon doesn't have paging by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
Use equivalent enable method.
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_os10_ssh.html b/docs/netmiko/dell/dell_os10_ssh.html
new file mode 100644
index 000000000..d0c3732ab
--- /dev/null
+++ b/docs/netmiko/dell/dell_os10_ssh.html
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+netmiko.dell.dell_os10_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_os10_ssh
+
+
+Dell EMC Networking OS10 Driver - supports dellos10.
+
+Source code
+"""Dell EMC Networking OS10 Driver - supports dellos10."""
+from typing import Any, Optional
+from netmiko.base_connection import BaseConnection
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.scp_handler import BaseFileTransfer
+import os
+import re
+
+
+class DellOS10SSH(CiscoSSHConnection):
+ """Dell EMC Networking OS10 Driver - supports dellos10."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class DellOS10FileTransfer(BaseFileTransfer):
+ """Dell EMC Networking OS10 SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/home/admin",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+ self.folder_name = "/config"
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_cmd = f'system "ls -l {self.file_system}/{remote_file}"'
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_out.splitlines():
+ if remote_file in line:
+ file_size = line.split()[4]
+ break
+ 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:
+ return int(file_size)
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) bytes free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f'system "df {self.folder_name}"'
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_output.splitlines():
+ if self.folder_name in line:
+ space_available = line.split()[-3]
+ break
+ return int(space_available)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"(.*) (.*)") -> str:
+ return super(DellOS10FileTransfer, DellOS10FileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+ def check_file_exists(self, remote_cmd: str = "dir home") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory contents .*{}".format(self.dest_file)
+ return bool(re.search(search_string, remote_out, flags=re.DOTALL))
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+
+
+
+
+
+
+
+
+class DellOS10FileTransfer
+(ssh_conn, source_file, dest_file, file_system='/home/admin', direction='put', **kwargs)
+
+-
+
Dell EMC Networking OS10 SCP File Transfer driver.
+
+Source code
+class DellOS10FileTransfer(BaseFileTransfer):
+ """Dell EMC Networking OS10 SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/home/admin",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+ self.folder_name = "/config"
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_cmd = f'system "ls -l {self.file_system}/{remote_file}"'
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_out.splitlines():
+ if remote_file in line:
+ file_size = line.split()[4]
+ break
+ 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:
+ return int(file_size)
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) bytes free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f'system "df {self.folder_name}"'
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_output.splitlines():
+ if self.folder_name in line:
+ space_available = line.split()[-3]
+ break
+ return int(space_available)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"(.*) (.*)") -> str:
+ return super(DellOS10FileTransfer, DellOS10FileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+ def check_file_exists(self, remote_cmd: str = "dir home") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory contents .*{}".format(self.dest_file)
+ return bool(re.search(search_string, remote_out, flags=re.DOTALL))
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+Ancestors
+
+Methods
+
+
+def remote_md5(self, base_cmd='verify /md5', remote_file=None)
+
+-
+
Calculate remote MD5 and returns the hash.
+
+Source code
+def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+
+
+Inherited members
+
+
+
+class DellOS10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell EMC Networking OS10 Driver - supports dellos10.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellOS10SSH(CiscoSSHConnection):
+ """Dell EMC Networking OS10 Driver - supports dellos10."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_powerconnect.html b/docs/netmiko/dell/dell_powerconnect.html
new file mode 100644
index 000000000..2080d71e4
--- /dev/null
+++ b/docs/netmiko/dell/dell_powerconnect.html
@@ -0,0 +1,902 @@
+
+
+
+
+
+
+netmiko.dell.dell_powerconnect API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_powerconnect
+
+
+Dell PowerConnect Driver.
+
+Source code
+"""Dell PowerConnect Driver."""
+from typing import Optional
+from paramiko import SSHClient
+import time
+from os import path
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class DellPowerConnectBase(CiscoBaseConnection):
+ """Dell PowerConnect Driver."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal datadump")
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def check_config_mode(
+ self, check_string: str = "(config)#", pattern: str = ""
+ ) -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+class DellPowerConnectSSH(DellPowerConnectBase):
+ """Dell PowerConnect Driver.
+
+ To make it work, we have to override the SSHClient _auth method.
+ If we use login/password, the ssh server use the (none) auth mechanism.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection.
+
+ See base_connection.py file for any updates.
+ """
+ # Create instance of SSHClient object
+ # If user does not provide SSH key, we use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Powerconnect presents with the following on login
+
+ User Name:
+
+ Password: ****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+class DellPowerConnectTelnet(DellPowerConnectBase):
+ """Dell PowerConnect Telnet Driver."""
+
+ pass
+
+
+
+
+
+
+
+
+
+class DellPowerConnectBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellPowerConnectBase(CiscoBaseConnection):
+ """Dell PowerConnect Driver."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal datadump")
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def check_config_mode(
+ self, check_string: str = "(config)#", pattern: str = ""
+ ) -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='(config)#', pattern='')
+
+-
+
Checks if the device is in configuration mode
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config)#", pattern: str = ""
+) -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal datadump")
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+class DellPowerConnectSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+To make it work, we have to override the SSHClient _auth method.
+If we use login/password, the ssh server use the (none) auth mechanism.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellPowerConnectSSH(DellPowerConnectBase):
+ """Dell PowerConnect Driver.
+
+ To make it work, we have to override the SSHClient _auth method.
+ If we use login/password, the ssh server use the (none) auth mechanism.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection.
+
+ See base_connection.py file for any updates.
+ """
+ # Create instance of SSHClient object
+ # If user does not provide SSH key, we use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Powerconnect presents with the following on login
+
+ User Name:
+
+ Password: ****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Powerconnect presents with the following on login
+User Name:
+Password: ****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Powerconnect presents with the following on login
+
+ User Name:
+
+ Password: ****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class DellPowerConnectTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Telnet Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellPowerConnectTelnet(DellPowerConnectBase):
+ """Dell PowerConnect Telnet Driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/dell_sonic_ssh.html b/docs/netmiko/dell/dell_sonic_ssh.html
new file mode 100644
index 000000000..1e4a7b507
--- /dev/null
+++ b/docs/netmiko/dell/dell_sonic_ssh.html
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+netmiko.dell.dell_sonic_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dell.dell_sonic_ssh
+
+
+Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution by Dell Technologies Driver
+- supports dellenterprisesonic.
+
+Source code
+"""
+Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution by Dell Technologies Driver
+- supports dellenterprisesonic.
+"""
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+
+
+class DellSonicSSH(NoEnable, CiscoSSHConnection):
+ """
+ Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+ by Dell Technologies Driver - supports dellenterprisesonic.
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the sonic-cli Shell."""
+ log.debug("Enter sonic-cli Shell.")
+ return self._send_command_str("sonic-cli", expect_string=r"\#")
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ return self._send_command_str("exit", expect_string=r"\$")
+
+
+
+
+
+
+
+
+
+class DellSonicSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+by Dell Technologies Driver - supports dellenterprisesonic.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellSonicSSH(NoEnable, CiscoSSHConnection):
+ """
+ Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+ by Dell Technologies Driver - supports dellenterprisesonic.
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the sonic-cli Shell."""
+ log.debug("Enter sonic-cli Shell.")
+ return self._send_command_str("sonic-cli", expect_string=r"\#")
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ return self._send_command_str("exit", expect_string=r"\$")
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dell/index.html b/docs/netmiko/dell/index.html
new file mode 100644
index 000000000..fb4385e7d
--- /dev/null
+++ b/docs/netmiko/dell/index.html
@@ -0,0 +1,2093 @@
+
+
+
+
+
+
+netmiko.dell API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.dell.dell_dnos6 import DellDNOS6SSH
+from netmiko.dell.dell_dnos6 import DellDNOS6Telnet
+from netmiko.dell.dell_force10_ssh import DellForce10SSH
+from netmiko.dell.dell_os10_ssh import DellOS10SSH, DellOS10FileTransfer
+from netmiko.dell.dell_sonic_ssh import DellSonicSSH
+from netmiko.dell.dell_powerconnect import DellPowerConnectSSH
+from netmiko.dell.dell_powerconnect import DellPowerConnectTelnet
+from netmiko.dell.dell_isilon_ssh import DellIsilonSSH
+
+__all__ = [
+ "DellForce10SSH",
+ "DellPowerConnectSSH",
+ "DellPowerConnectTelnet",
+ "DellOS10SSH",
+ "DellSonicSSH",
+ "DellOS10FileTransfer",
+ "DellIsilonSSH",
+ "DellDNOS6SSH",
+ "DellDNOS6Telnet",
+]
+
+
+
+
+
+
+
+
+
+class DellDNOS6SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellDNOS6SSH(DellDNOS6Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DellDNOS6Telnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellDNOS6Telnet(DellDNOS6Base):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DellForce10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell Force10 Driver - supports DNOS9.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellForce10SSH(CiscoSSHConnection):
+ """Dell Force10 Driver - supports DNOS9."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class DellIsilonSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellIsilonSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+ def _zsh_mode(self, prompt_terminator: str = "$") -> None:
+ """Run zsh command to unify the environment"""
+ if self.global_delay_factor < 1:
+ delay_factor = 1.0
+ else:
+ delay_factor = self.global_delay_factor
+ command = self.RETURN + "zsh" + self.RETURN
+ self.write_channel(command)
+ time.sleep(0.25 * delay_factor)
+ self._set_prompt(prompt_terminator)
+ time.sleep(0.25 * delay_factor)
+ self.clear_buffer()
+
+ def _set_prompt(self, prompt_terminator: str = "$") -> None:
+ prompt = f"PROMPT='%m{prompt_terminator}'"
+ command = self.RETURN + prompt + self.RETURN
+ self.write_channel(command)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "sudo su",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ delay_factor = self.select_delay_factor(delay_factor=1)
+ output = ""
+ if not self.check_enable_mode():
+ output += self._send_command_timing_str(
+ cmd, strip_prompt=False, strip_command=False
+ )
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_pattern(pattern=r"#.*$")
+ time.sleep(1 * delay_factor)
+ self._set_prompt(prompt_terminator="#")
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode")
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
+
+Ancestors
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Use equivalent enable method.
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+
+
+def config_mode(self, config_command='sudo su', pattern='ssword', re_flags=)
+
+-
+
Use equivalent enable method.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Isilon doesn't have paging by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='')
+
+-
+
Use equivalent enable method.
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+
+
+Inherited members
+
+
+
+class DellOS10FileTransfer
+(ssh_conn, source_file, dest_file, file_system='/home/admin', direction='put', **kwargs)
+
+-
+
Dell EMC Networking OS10 SCP File Transfer driver.
+
+Source code
+class DellOS10FileTransfer(BaseFileTransfer):
+ """Dell EMC Networking OS10 SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/home/admin",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+ self.folder_name = "/config"
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_cmd = f'system "ls -l {self.file_system}/{remote_file}"'
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_out.splitlines():
+ if remote_file in line:
+ file_size = line.split()[4]
+ break
+ 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:
+ return int(file_size)
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) bytes free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f'system "df {self.folder_name}"'
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_output.splitlines():
+ if self.folder_name in line:
+ space_available = line.split()[-3]
+ break
+ return int(space_available)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"(.*) (.*)") -> str:
+ return super(DellOS10FileTransfer, DellOS10FileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+ def check_file_exists(self, remote_cmd: str = "dir home") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory contents .*{}".format(self.dest_file)
+ return bool(re.search(search_string, remote_out, flags=re.DOTALL))
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+Ancestors
+
+Methods
+
+
+def remote_md5(self, base_cmd='verify /md5', remote_file=None)
+
+-
+
Calculate remote MD5 and returns the hash.
+
+Source code
+def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+
+
+Inherited members
+
+
+
+class DellOS10SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell EMC Networking OS10 Driver - supports dellos10.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellOS10SSH(CiscoSSHConnection):
+ """Dell EMC Networking OS10 Driver - supports dellos10."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class DellPowerConnectSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Driver.
+To make it work, we have to override the SSHClient _auth method.
+If we use login/password, the ssh server use the (none) auth mechanism.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellPowerConnectSSH(DellPowerConnectBase):
+ """Dell PowerConnect Driver.
+
+ To make it work, we have to override the SSHClient _auth method.
+ If we use login/password, the ssh server use the (none) auth mechanism.
+ """
+
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection.
+
+ See base_connection.py file for any updates.
+ """
+ # Create instance of SSHClient object
+ # If user does not provide SSH key, we use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Powerconnect presents with the following on login
+
+ User Name:
+
+ Password: ****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Powerconnect presents with the following on login
+User Name:
+Password: ****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Powerconnect presents with the following on login
+
+ User Name:
+
+ Password: ****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class DellPowerConnectTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell PowerConnect Telnet Driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellPowerConnectTelnet(DellPowerConnectBase):
+ """Dell PowerConnect Telnet Driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DellSonicSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+by Dell Technologies Driver - supports dellenterprisesonic.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DellSonicSSH(NoEnable, CiscoSSHConnection):
+ """
+ Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+ by Dell Technologies Driver - supports dellenterprisesonic.
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the sonic-cli Shell."""
+ log.debug("Enter sonic-cli Shell.")
+ return self._send_command_str("sonic-cli", expect_string=r"\#")
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ return self._send_command_str("exit", expect_string=r"\$")
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dlink/dlink_ds.html b/docs/netmiko/dlink/dlink_ds.html
new file mode 100644
index 000000000..8d2ae473b
--- /dev/null
+++ b/docs/netmiko/dlink/dlink_ds.html
@@ -0,0 +1,703 @@
+
+
+
+
+
+
+netmiko.dlink.dlink_ds API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.dlink.dlink_ds
+
+
+
+Source code
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class DlinkDSBase(NoEnable, NoConfig, CiscoSSHConnection):
+ """Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)"""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Return paging before disconnect"""
+ self.send_command_timing("enable clipaging")
+ return super().cleanup(command=command)
+
+
+class DlinkDSSSH(DlinkDSBase):
+ pass
+
+
+class DlinkDSTelnet(DlinkDSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class DlinkDSBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DlinkDSBase(NoEnable, NoConfig, CiscoSSHConnection):
+ """Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)"""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Return paging before disconnect"""
+ self.send_command_timing("enable clipaging")
+ return super().cleanup(command=command)
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def cleanup(self, command='logout')
+
+-
+
Return paging before disconnect
+
+Source code
+def cleanup(self, command: str = "logout") -> None:
+ """Return paging before disconnect"""
+ self.send_command_timing("enable clipaging")
+ return super().cleanup(command=command)
+
+
+
+def save_config(self, cmd='save', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves configuration."""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+
+
+
+Inherited members
+
+
+
+class DlinkDSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DlinkDSSSH(DlinkDSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DlinkDSTelnet
+(*args, **kwargs)
+
+-
+
Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DlinkDSTelnet(DlinkDSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/dlink/index.html b/docs/netmiko/dlink/index.html
new file mode 100644
index 000000000..e40cf2bae
--- /dev/null
+++ b/docs/netmiko/dlink/index.html
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+netmiko.dlink API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.dlink.dlink_ds import DlinkDSTelnet, DlinkDSSSH
+
+__all__ = ["DlinkDSTelnet", "DlinkDSSSH"]
+
+
+
+
+
+
+
+
+
+class DlinkDSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DlinkDSSSH(DlinkDSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class DlinkDSTelnet
+(*args, **kwargs)
+
+-
+
Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class DlinkDSTelnet(DlinkDSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/eltex/eltex_esr_ssh.html b/docs/netmiko/eltex/eltex_esr_ssh.html
new file mode 100644
index 000000000..6e3d79389
--- /dev/null
+++ b/docs/netmiko/eltex/eltex_esr_ssh.html
@@ -0,0 +1,602 @@
+
+
+
+
+
+
+netmiko.eltex.eltex_esr_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.eltex.eltex_esr_ssh
+
+
+
+Source code
+from typing import Optional, Any
+import warnings
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class EltexEsrSSH(CiscoSSHConnection):
+ """Netmiko support for routers Eltex ESR."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+ ) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+ def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _confirm(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Confirm the candidate configuration.
+ Raise an error and return the failure if the confirm fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Nothing to confirm in configuration"
+ command_string = "confirm"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Confirm failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _restore(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Restore the candidate configuration.
+
+ Raise an error and return the failure if the restore fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't find backup of previous configuration!"
+ command_string = "restore"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Restore failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+
+
+
+
+
+
+
+
+-
+
Netmiko support for routers Eltex ESR.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EltexEsrSSH(CiscoSSHConnection):
+ """Netmiko support for routers Eltex ESR."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+ ) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+ def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _confirm(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Confirm the candidate configuration.
+ Raise an error and return the failure if the confirm fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Nothing to confirm in configuration"
+ command_string = "confirm"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Confirm failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _restore(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Restore the candidate configuration.
+
+ Raise an error and return the failure if the restore fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't find backup of previous configuration!"
+ command_string = "restore"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Restore failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
Checks whether in configuration mode. Returns a boolean.
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration.
+Raise an error and return the failure
+if the commit fails.
+default:
+command_string = commit
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+-
+
Not Implemented (use commit() method)
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/eltex/eltex_ssh.html b/docs/netmiko/eltex/eltex_ssh.html
new file mode 100644
index 000000000..9dd3cc8d5
--- /dev/null
+++ b/docs/netmiko/eltex/eltex_ssh.html
@@ -0,0 +1,291 @@
+
+
+
+
+
+
+netmiko.eltex.eltex_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.eltex.eltex_ssh
+
+
+
+Source code
+from typing import Any
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class EltexSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class EltexSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EltexSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/eltex/index.html b/docs/netmiko/eltex/index.html
new file mode 100644
index 000000000..d8e17cec8
--- /dev/null
+++ b/docs/netmiko/eltex/index.html
@@ -0,0 +1,705 @@
+
+
+
+
+
+
+netmiko.eltex API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.eltex.eltex_ssh import EltexSSH
+from netmiko.eltex.eltex_esr_ssh import EltexEsrSSH
+
+__all__ = ["EltexSSH", "EltexEsrSSH"]
+
+
+
+
+
+
+
+
+
+-
+
Netmiko support for routers Eltex ESR.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EltexEsrSSH(CiscoSSHConnection):
+ """Netmiko support for routers Eltex ESR."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+ ) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+ def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _confirm(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Confirm the candidate configuration.
+ Raise an error and return the failure if the confirm fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Nothing to confirm in configuration"
+ command_string = "confirm"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Confirm failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _restore(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Restore the candidate configuration.
+
+ Raise an error and return the failure if the restore fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't find backup of previous configuration!"
+ command_string = "restore"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Restore failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
Checks whether in configuration mode. Returns a boolean.
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration.
+Raise an error and return the failure
+if the commit fails.
+default:
+command_string = commit
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+-
+
Not Implemented (use commit() method)
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+
+
+Inherited members
+
+
+
+class EltexSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EltexSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/endace/endace_ssh.html b/docs/netmiko/endace/endace_ssh.html
new file mode 100644
index 000000000..ed518a022
--- /dev/null
+++ b/docs/netmiko/endace/endace_ssh.html
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+netmiko.endace.endace_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.endace.endace_ssh
+
+
+
+Source code
+from typing import Optional
+from netmiko.cisco_base_connection import CiscoSSHConnection
+import re
+
+
+class EndaceSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="no cli session paging enable")
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "conf t", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ output = ""
+ if not self.check_config_mode():
+ output += self._send_command_timing_str(
+ config_command, strip_command=False, strip_prompt=False
+ )
+ if "to enter configuration mode anyway" in output:
+ output += self._send_command_timing_str(
+ "YES", strip_command=False, strip_prompt=False
+ )
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ self.config_mode()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class EndaceSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EndaceSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="no cli session paging enable")
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "conf t", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ output = ""
+ if not self.check_config_mode():
+ output += self._send_command_timing_str(
+ config_command, strip_command=False, strip_prompt=False
+ )
+ if "to enter configuration mode anyway" in output:
+ output += self._send_command_timing_str(
+ "YES", strip_command=False, strip_prompt=False
+ )
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ self.config_mode()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/endace/index.html b/docs/netmiko/endace/index.html
new file mode 100644
index 000000000..38d4ba2f8
--- /dev/null
+++ b/docs/netmiko/endace/index.html
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+netmiko.endace API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.endace.endace_ssh import EndaceSSH
+
+__all__ = ["EndaceSSH"]
+
+
+
+
+
+
+
+
+
+class EndaceSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EndaceSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="no cli session paging enable")
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "conf t", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ output = ""
+ if not self.check_config_mode():
+ output += self._send_command_timing_str(
+ config_command, strip_command=False, strip_prompt=False
+ )
+ if "to enter configuration mode anyway" in output:
+ output += self._send_command_timing_str(
+ "YES", strip_command=False, strip_prompt=False
+ )
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ self.config_mode()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/enterasys/enterasys_ssh.html b/docs/netmiko/enterasys/enterasys_ssh.html
new file mode 100644
index 000000000..005449156
--- /dev/null
+++ b/docs/netmiko/enterasys/enterasys_ssh.html
@@ -0,0 +1,294 @@
+
+
+
+
+
+
+netmiko.enterasys.enterasys_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.enterasys.enterasys_ssh
+
+
+Enterasys support.
+
+Source code
+"""Enterasys support."""
+from typing import Any
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class EnterasysSSH(CiscoSSHConnection):
+ """Enterasys support."""
+
+ def session_preparation(self) -> None:
+ """Enterasys requires enable mode to disable paging."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ self.disable_paging(command="set length 0")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class EnterasysSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Enterasys support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EnterasysSSH(CiscoSSHConnection):
+ """Enterasys support."""
+
+ def session_preparation(self) -> None:
+ """Enterasys requires enable mode to disable paging."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ self.disable_paging(command="set length 0")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Enterasys requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """Enterasys requires enable mode to disable paging."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ self.disable_paging(command="set length 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/enterasys/index.html b/docs/netmiko/enterasys/index.html
new file mode 100644
index 000000000..ffd9388f0
--- /dev/null
+++ b/docs/netmiko/enterasys/index.html
@@ -0,0 +1,291 @@
+
+
+
+
+
+
+netmiko.enterasys API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.enterasys
+
+
+
+Source code
+from netmiko.enterasys.enterasys_ssh import EnterasysSSH
+
+__all__ = ["EnterasysSSH"]
+
+
+
+
+
+
+
+
+
+class EnterasysSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Enterasys support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EnterasysSSH(CiscoSSHConnection):
+ """Enterasys support."""
+
+ def session_preparation(self) -> None:
+ """Enterasys requires enable mode to disable paging."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ self.disable_paging(command="set length 0")
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Enterasys requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """Enterasys requires enable mode to disable paging."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ self.disable_paging(command="set length 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ericsson/ericsson_ipos.html b/docs/netmiko/ericsson/ericsson_ipos.html
new file mode 100644
index 000000000..afb38cfe6
--- /dev/null
+++ b/docs/netmiko/ericsson/ericsson_ipos.html
@@ -0,0 +1,662 @@
+
+
+
+
+
+
+netmiko.ericsson.ericsson_ipos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ericsson.ericsson_ipos
+
+
+Ericsson Ipos looks like it was RedBack equipment.
+
+Source code
+"""
+Ericsson Ipos looks like it was RedBack equipment.
+"""
+from typing import Optional, Any, Union, Sequence, TextIO
+import re
+import warnings
+
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class EricssonIposSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern=r"terminal")
+ self.disable_paging()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable 15",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ """
+ 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 send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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 save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+ ) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ self.exit_config_mode()
+
+ return output
+
+
+
+
+
+
+
+
+
+class EricssonIposSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EricssonIposSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern=r"terminal")
+ self.disable_paging()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable 15",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ """
+ 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 send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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 save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+ ) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ 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 commit(self, confirm=False, confirm_delay=None, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ 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 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: str = "end", pattern: str = "#") -> str:
+ """
+ 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')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ 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: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """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..28fcbdade
--- /dev/null
+++ b/docs/netmiko/ericsson/index.html
@@ -0,0 +1,530 @@
+
+
+
+
+
+
+netmiko.ericsson API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ericsson
+
+
+
+Source code
+from netmiko.ericsson.ericsson_ipos import EricssonIposSSH
+
+__all__ = ["EricssonIposSSH"]
+
+
+
+
+
+
+
+
+
+class EricssonIposSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class EricssonIposSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern=r"terminal")
+ self.disable_paging()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable 15",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ """
+ 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 send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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 save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+ ) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ 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 commit(self, confirm=False, confirm_delay=None, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ 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 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: str = "end", pattern: str = "#") -> str:
+ """
+ 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')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ 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: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """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/exceptions.html b/docs/netmiko/exceptions.html
new file mode 100644
index 000000000..ad8b6a8fb
--- /dev/null
+++ b/docs/netmiko/exceptions.html
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+netmiko.exceptions API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.exceptions
+
+
+
+Source code
+from paramiko.ssh_exception import SSHException
+from paramiko.ssh_exception import AuthenticationException
+
+
+class NetmikoBaseException(Exception):
+ """General base exception except for exceptions that inherit from Paramiko."""
+
+ pass
+
+
+class ConnectionException(NetmikoBaseException):
+ """Generic exception indicating the connection failed."""
+
+ pass
+
+
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+
+NetMikoTimeoutException = NetmikoTimeoutException
+
+
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+
+NetMikoAuthenticationException = NetmikoAuthenticationException
+
+
+class ConfigInvalidException(NetmikoBaseException):
+ """Exception raised for invalid configuration error."""
+
+ pass
+
+
+class WriteException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko write operation."""
+
+ pass
+
+
+class ReadException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+
+class ReadTimeout(ReadException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+
+
+
+
+
+
+
+
+class ConfigInvalidException
+(*args, **kwargs)
+
+-
+
Exception raised for invalid configuration error.
+
+Source code
+class ConfigInvalidException(NetmikoBaseException):
+ """Exception raised for invalid configuration error."""
+
+ pass
+
+Ancestors
+
+
+
+class ConnectionException
+(*args, **kwargs)
+
+-
+
Generic exception indicating the connection failed.
+
+Source code
+class ConnectionException(NetmikoBaseException):
+ """Generic exception indicating the connection failed."""
+
+ pass
+
+Ancestors
+
+
+
+class NetMikoAuthenticationException
+(*args, **kwargs)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetMikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoAuthenticationException
+(*args, **kwargs)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoBaseException
+(*args, **kwargs)
+
+-
+
General base exception except for exceptions that inherit from Paramiko.
+
+Source code
+class NetmikoBaseException(Exception):
+ """General base exception except for exceptions that inherit from Paramiko."""
+
+ pass
+
+Ancestors
+
+- builtins.Exception
+- builtins.BaseException
+
+Subclasses
+
+
+
+class NetmikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class ReadException
+(*args, **kwargs)
+
+-
+
General exception indicating an error occurred during a Netmiko read operation.
+
+Source code
+class ReadException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+Ancestors
+
+Subclasses
+
+
+
+class ReadTimeout
+(*args, **kwargs)
+
+-
+
General exception indicating an error occurred during a Netmiko read operation.
+
+Source code
+class ReadTimeout(ReadException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+Ancestors
+
+
+
+class WriteException
+(*args, **kwargs)
+
+-
+
General exception indicating an error occurred during a Netmiko write operation.
+
+Source code
+class WriteException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko write operation."""
+
+ pass
+
+Ancestors
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_ers_ssh.html b/docs/netmiko/extreme/extreme_ers_ssh.html
new file mode 100644
index 000000000..c64ffbdb0
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_ers_ssh.html
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_ers_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_ers_ssh
+
+
+Netmiko support for Extreme Ethernet Routing Switch.
+
+Source code
+"""Netmiko support for Extreme Ethernet Routing Switch."""
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+# Extreme ERS presents Enter Ctrl-Y to begin.
+CTRL_Y = "\x19"
+
+
+class ExtremeErsSSH(CiscoSSHConnection):
+ """Netmiko support for Extreme Ethernet Routing Switch."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+-
+
Netmiko support for Extreme Ethernet Routing Switch.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeErsSSH(CiscoSSHConnection):
+ """Netmiko support for Extreme Ethernet Routing Switch."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Extreme ERS presents the following as part of the login process:
+Enter Ctrl-Y to begin.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_exos.html b/docs/netmiko/extreme/extreme_exos.html
new file mode 100644
index 000000000..17a149b9a
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_exos.html
@@ -0,0 +1,1161 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_exos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_exos
+
+
+Extreme support.
+
+Source code
+"""Extreme support."""
+import os
+from typing import Any, Callable, Optional, Union, List, Dict
+import re
+from netmiko.base_connection import BaseConnection
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.scp_handler import BaseFileTransfer
+
+
+class ExtremeExosBase(NoConfig, CiscoSSHConnection):
+ """Extreme Exos support.
+
+ Designed for EXOS >= 15.0
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+ self.send_command_timing("disable cli prompting")
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Extreme attaches an id to the prompt. The id increases with every command.
+ It needs to br stripped off to match the prompt. Eg.
+
+ testhost.1 #
+ testhost.2 #
+ testhost.3 #
+
+ If new config is loaded and not saved yet, a '* ' prefix appears before the
+ prompt, eg.
+
+ * testhost.4 #
+ * testhost.5 #
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ # Strip off any leading * or whitespace chars; strip off trailing period and digits
+ match = re.search(r"[\*\s]*(.*)\.\d+", cur_base_prompt)
+ if match:
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return self.base_prompt
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Extreme needs special handler here due to the prompt changes."""
+
+ # Change send_command behavior to use self.base_prompt
+ kwargs.setdefault("auto_find_prompt", False)
+
+ # refresh self.base_prompt
+ self.set_base_prompt()
+ return super().send_command(*args, **kwargs)
+
+ def save_config(
+ self,
+ cmd: str = "save configuration primary",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class ExtremeExosSSH(ExtremeExosBase):
+ pass
+
+
+class ExtremeExosTelnet(ExtremeExosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class ExtremeExosFileTransfer(BaseFileTransfer):
+ """Extreme EXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/usr/local/cfg",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def remote_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"ls {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "Invalid pathname" in remote_output
+ or "No such file or directory" in remote_output
+ ):
+ msg = f"Invalid file_system: {self.file_system}"
+ else:
+ match = re.search(search_pattern, remote_output)
+ if match:
+ return int(match.group(1))
+ else:
+ msg = f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ raise ValueError(msg)
+
+ def verify_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ return super().verify_space_available(search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ return False
+ elif self.dest_file 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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"ls {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ line = match.group(0)
+ # Format will be: -rw-r--r-- 1 admin admin 3934 Jan 24 03:50 filename
+ # Format will be: "-rw-r--r-- 1 admin admin 3934 Jan 24 2022 filename"
+ file_size = line.split()[4]
+ else:
+ raise IOError("Unable to parse 'ls' output in remote_file_size method")
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ raise IOError("Unable to find file on remote system")
+ else:
+ return int(file_size)
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def compare_md5(self) -> bool:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support an enable SCP operation. SCP is always enabled."
+ raise AttributeError(msg)
+
+ def disable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support a disable SCP operation."
+ raise AttributeError(msg)
+
+ def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+
+
+
+
+
+
+
+
+class ExtremeExosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme Exos support.
+Designed for EXOS >= 15.0
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeExosBase(NoConfig, CiscoSSHConnection):
+ """Extreme Exos support.
+
+ Designed for EXOS >= 15.0
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+ self.send_command_timing("disable cli prompting")
+
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Extreme attaches an id to the prompt. The id increases with every command.
+ It needs to br stripped off to match the prompt. Eg.
+
+ testhost.1 #
+ testhost.2 #
+ testhost.3 #
+
+ If new config is loaded and not saved yet, a '* ' prefix appears before the
+ prompt, eg.
+
+ * testhost.4 #
+ * testhost.5 #
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ # Strip off any leading * or whitespace chars; strip off trailing period and digits
+ match = re.search(r"[\*\s]*(.*)\.\d+", cur_base_prompt)
+ if match:
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return self.base_prompt
+
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Extreme needs special handler here due to the prompt changes."""
+
+ # Change send_command behavior to use self.base_prompt
+ kwargs.setdefault("auto_find_prompt", False)
+
+ # refresh self.base_prompt
+ self.set_base_prompt()
+ return super().send_command(*args, **kwargs)
+
+ def save_config(
+ self,
+ cmd: str = "save configuration primary",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='save configuration primary', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save configuration primary",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def send_command(self, *args, **kwargs)
+
+-
+
Extreme needs special handler here due to the prompt changes.
+
+Source code
+def send_command(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Extreme needs special handler here due to the prompt changes."""
+
+ # Change send_command behavior to use self.base_prompt
+ kwargs.setdefault("auto_find_prompt", False)
+
+ # refresh self.base_prompt
+ self.set_base_prompt()
+ return super().send_command(*args, **kwargs)
+
+
+
+def set_base_prompt(self, *args, **kwargs)
+
+-
+
Extreme attaches an id to the prompt. The id increases with every command.
+It needs to br stripped off to match the prompt. Eg.
+testhost.1 #
+testhost.2 #
+testhost.3 #
+
+If new config is loaded and not saved yet, a '* ' prefix appears before the
+prompt, eg.
+* testhost.4 #
+* testhost.5 #
+
+
+Source code
+def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """
+ Extreme attaches an id to the prompt. The id increases with every command.
+ It needs to br stripped off to match the prompt. Eg.
+
+ testhost.1 #
+ testhost.2 #
+ testhost.3 #
+
+ If new config is loaded and not saved yet, a '* ' prefix appears before the
+ prompt, eg.
+
+ * testhost.4 #
+ * testhost.5 #
+ """
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ # Strip off any leading * or whitespace chars; strip off trailing period and digits
+ match = re.search(r"[\*\s]*(.*)\.\d+", cur_base_prompt)
+ if match:
+ self.base_prompt = match.group(1)
+ return self.base_prompt
+ else:
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+class ExtremeExosFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/usr/local/cfg', direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=False)
+
+-
+
Extreme EXOS SCP File Transfer driver.
+
+Source code
+class ExtremeExosFileTransfer(BaseFileTransfer):
+ """Extreme EXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/usr/local/cfg",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def remote_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"ls {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "Invalid pathname" in remote_output
+ or "No such file or directory" in remote_output
+ ):
+ msg = f"Invalid file_system: {self.file_system}"
+ else:
+ match = re.search(search_pattern, remote_output)
+ if match:
+ return int(match.group(1))
+ else:
+ msg = f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ raise ValueError(msg)
+
+ def verify_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ return super().verify_space_available(search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ return False
+ elif self.dest_file 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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"ls {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ line = match.group(0)
+ # Format will be: -rw-r--r-- 1 admin admin 3934 Jan 24 03:50 filename
+ # Format will be: "-rw-r--r-- 1 admin admin 3934 Jan 24 2022 filename"
+ file_size = line.split()[4]
+ else:
+ raise IOError("Unable to parse 'ls' output in remote_file_size method")
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ raise IOError("Unable to find file on remote system")
+ else:
+ return int(file_size)
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def compare_md5(self) -> bool:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support an enable SCP operation. SCP is always enabled."
+ raise AttributeError(msg)
+
+ def disable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support a disable SCP operation."
+ raise AttributeError(msg)
+
+ def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+Ancestors
+
+Methods
+
+
+def verify_file(self)
+
+-
+
Verify the file has been transferred correctly based on filesize.
+
+Source code
+def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+
+
+Inherited members
+
+
+
+class ExtremeExosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme Exos support.
+Designed for EXOS >= 15.0
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeExosSSH(ExtremeExosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ExtremeExosTelnet
+(*args, **kwargs)
+
+-
+
Extreme Exos support.
+Designed for EXOS >= 15.0
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeExosTelnet(ExtremeExosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_netiron.html b/docs/netmiko/extreme/extreme_netiron.html
new file mode 100644
index 000000000..d886f564e
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_netiron.html
@@ -0,0 +1,677 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_netiron API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_netiron
+
+
+
+Source code
+from typing import Any
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeNetironBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="skip-page-display")
+ self.set_terminal_width()
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class ExtremeNetironSSH(ExtremeNetironBase):
+ pass
+
+
+class ExtremeNetironTelnet(ExtremeNetironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class ExtremeNetironBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNetironBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="skip-page-display")
+ self.set_terminal_width()
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="skip-page-display")
+ self.set_terminal_width()
+
+
+
+Inherited members
+
+
+
+class ExtremeNetironSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNetironSSH(ExtremeNetironBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ExtremeNetironTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNetironTelnet(ExtremeNetironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_nos_ssh.html b/docs/netmiko/extreme/extreme_nos_ssh.html
new file mode 100644
index 000000000..cb8b66973
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_nos_ssh.html
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_nos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_nos_ssh
+
+
+Support for Extreme NOS/VDX.
+
+Source code
+"""Support for Extreme NOS/VDX."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeNosSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme NOS/VDX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class ExtremeNosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme NOS/VDX.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNosSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme NOS/VDX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=True, confirm_response='y')
+
+-
+
Save Config for Extreme VDX.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_slx_ssh.html b/docs/netmiko/extreme/extreme_slx_ssh.html
new file mode 100644
index 000000000..944ed4224
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_slx_ssh.html
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_slx_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_slx_ssh
+
+
+Support for Extreme SLX.
+
+Source code
+"""Support for Extreme SLX."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeSlxSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme SLX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class ExtremeSlxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme SLX.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeSlxSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme SLX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=True, confirm_response='y')
+
+-
+
Save Config for Extreme SLX.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_tierraos_ssh.html b/docs/netmiko/extreme/extreme_tierraos_ssh.html
new file mode 100644
index 000000000..386008678
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_tierraos_ssh.html
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_tierraos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_tierraos_ssh
+
+
+Support for Extreme TierraOS.
+
+Source code
+"""Support for Extreme TierraOS."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeTierraSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme TierraOS."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class ExtremeTierraSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme TierraOS.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeTierraSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme TierraOS."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy run flash://config-file/startup-config', confirm=False, confirm_response='y')
+
+-
+
Save Config for Extreme TierraOS.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_vsp_ssh.html b/docs/netmiko/extreme/extreme_vsp_ssh.html
new file mode 100644
index 000000000..973c6bd98
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_vsp_ssh.html
@@ -0,0 +1,314 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_vsp_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_vsp_ssh
+
+
+Extreme Virtual Services Platform Support.
+
+Source code
+"""Extreme Virtual Services Platform Support."""
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeVspSSH(CiscoSSHConnection):
+ """Extreme Virtual Services Platform Support."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class ExtremeVspSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme Virtual Services Platform Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeVspSSH(CiscoSSHConnection):
+ """Extreme Virtual Services Platform Support."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/extreme_wing_ssh.html b/docs/netmiko/extreme/extreme_wing_ssh.html
new file mode 100644
index 000000000..214b0aa62
--- /dev/null
+++ b/docs/netmiko/extreme/extreme_wing_ssh.html
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+netmiko.extreme.extreme_wing_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme.extreme_wing_ssh
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeWingSSH(CiscoSSHConnection):
+ """Extreme WiNG support."""
+
+ def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
+ self.disable_paging(command="no page")
+
+
+
+
+
+
+
+
+
+class ExtremeWingSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme WiNG support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeWingSSH(CiscoSSHConnection):
+ """Extreme WiNG support."""
+
+ def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
+ self.disable_paging(command="no page")
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Disable paging and set Max term width
+
+Source code
+def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
+ self.disable_paging(command="no page")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/extreme/index.html b/docs/netmiko/extreme/index.html
new file mode 100644
index 000000000..7f7f87590
--- /dev/null
+++ b/docs/netmiko/extreme/index.html
@@ -0,0 +1,2449 @@
+
+
+
+
+
+
+netmiko.extreme API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.extreme
+
+
+
+Source code
+from netmiko.extreme.extreme_ers_ssh import ExtremeErsSSH
+from netmiko.extreme.extreme_exos import ExtremeExosSSH, ExtremeExosFileTransfer
+from netmiko.extreme.extreme_exos import ExtremeExosTelnet
+from netmiko.extreme.extreme_netiron import ExtremeNetironSSH
+from netmiko.extreme.extreme_netiron import ExtremeNetironTelnet
+from netmiko.extreme.extreme_nos_ssh import ExtremeNosSSH
+from netmiko.extreme.extreme_slx_ssh import ExtremeSlxSSH
+from netmiko.extreme.extreme_tierraos_ssh import ExtremeTierraSSH
+from netmiko.extreme.extreme_vsp_ssh import ExtremeVspSSH
+from netmiko.extreme.extreme_wing_ssh import ExtremeWingSSH
+
+__all__ = [
+ "ExtremeErsSSH",
+ "ExtremeExosSSH",
+ "ExtremeExosTelnet",
+ "ExtremeExosFileTransfer",
+ "ExtremeNetironSSH",
+ "ExtremeNetironTelnet",
+ "ExtremeNosSSH",
+ "ExtremeSlxSSH",
+ "ExtremeTierraSSH",
+ "ExtremeVspSSH",
+ "ExtremeWingSSH",
+]
+
+
+
+
+
+
+
+
+
+-
+
Netmiko support for Extreme Ethernet Routing Switch.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeErsSSH(CiscoSSHConnection):
+ """Netmiko support for Extreme Ethernet Routing Switch."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Extreme ERS presents the following as part of the login process:
+Enter Ctrl-Y to begin.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class ExtremeExosFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/usr/local/cfg', direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=False)
+
+-
+
Extreme EXOS SCP File Transfer driver.
+
+Source code
+class ExtremeExosFileTransfer(BaseFileTransfer):
+ """Extreme EXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/usr/local/cfg",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def remote_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"ls {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "Invalid pathname" in remote_output
+ or "No such file or directory" in remote_output
+ ):
+ msg = f"Invalid file_system: {self.file_system}"
+ else:
+ match = re.search(search_pattern, remote_output)
+ if match:
+ return int(match.group(1))
+ else:
+ msg = f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ raise ValueError(msg)
+
+ def verify_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ return super().verify_space_available(search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ return False
+ elif self.dest_file 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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"ls {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ line = match.group(0)
+ # Format will be: -rw-r--r-- 1 admin admin 3934 Jan 24 03:50 filename
+ # Format will be: "-rw-r--r-- 1 admin admin 3934 Jan 24 2022 filename"
+ file_size = line.split()[4]
+ else:
+ raise IOError("Unable to parse 'ls' output in remote_file_size method")
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ raise IOError("Unable to find file on remote system")
+ else:
+ return int(file_size)
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def compare_md5(self) -> bool:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support an enable SCP operation. SCP is always enabled."
+ raise AttributeError(msg)
+
+ def disable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support a disable SCP operation."
+ raise AttributeError(msg)
+
+ def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+Ancestors
+
+Methods
+
+
+def verify_file(self)
+
+-
+
Verify the file has been transferred correctly based on filesize.
+
+Source code
+def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+
+
+Inherited members
+
+
+
+class ExtremeExosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme Exos support.
+Designed for EXOS >= 15.0
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeExosSSH(ExtremeExosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ExtremeExosTelnet
+(*args, **kwargs)
+
+-
+
Extreme Exos support.
+Designed for EXOS >= 15.0
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeExosTelnet(ExtremeExosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+class ExtremeNetironSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNetironSSH(ExtremeNetironBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ExtremeNetironTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNetironTelnet(ExtremeNetironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+class ExtremeNosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme NOS/VDX.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeNosSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme NOS/VDX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=True, confirm_response='y')
+
+-
+
Save Config for Extreme VDX.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+class ExtremeSlxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme SLX.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeSlxSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme SLX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=True, confirm_response='y')
+
+-
+
Save Config for Extreme SLX.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+class ExtremeTierraSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Support for Extreme TierraOS.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeTierraSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme TierraOS."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy run flash://config-file/startup-config', confirm=False, confirm_response='y')
+
+-
+
Save Config for Extreme TierraOS.
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Adding a delay after login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+
+
+Inherited members
+
+
+
+class ExtremeVspSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme Virtual Services Platform Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeVspSSH(CiscoSSHConnection):
+ """Extreme Virtual Services Platform Support."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+
+
+Inherited members
+
+
+
+class ExtremeWingSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Extreme WiNG support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ExtremeWingSSH(CiscoSSHConnection):
+ """Extreme WiNG support."""
+
+ def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
+ self.disable_paging(command="no page")
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Disable paging and set Max term width
+
+Source code
+def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
+ self.disable_paging(command="no page")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/f5/f5_linux_ssh.html b/docs/netmiko/f5/f5_linux_ssh.html
new file mode 100644
index 000000000..b0f37d060
--- /dev/null
+++ b/docs/netmiko/f5/f5_linux_ssh.html
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+netmiko.f5.f5_linux_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.f5.f5_linux_ssh
+
+
+
+Source code
+from netmiko.linux.linux_ssh import LinuxSSH
+
+
+class F5LinuxSSH(LinuxSSH):
+ pass
+
+
+
+
+
+
+
+
+
+class F5LinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class F5LinuxSSH(LinuxSSH):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/f5/f5_tmsh_ssh.html b/docs/netmiko/f5/f5_tmsh_ssh.html
new file mode 100644
index 000000000..6e1e2772b
--- /dev/null
+++ b/docs/netmiko/f5/f5_tmsh_ssh.html
@@ -0,0 +1,382 @@
+
+
+
+
+
+
+netmiko.f5.f5_tmsh_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.f5.f5_tmsh_ssh
+
+
+
+Source code
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class F5TmshSSH(NoConfig, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+ def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+ def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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)
+
+
+
+
+
+
+
+
+
+class F5TmshSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class F5TmshSSH(NoConfig, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+ def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+ def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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)
+
+Ancestors
+
+Methods
+
+
+def cleanup(self, command='exit')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """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 exit_tmsh(self)
+
+-
+
+
+Source code
+def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+
+
+def tmsh_mode(self, delay_factor=1.0)
+
+-
+
tmsh command is equivalent to config command on F5.
+
+Source code
+def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/f5/index.html b/docs/netmiko/f5/index.html
new file mode 100644
index 000000000..060266f0b
--- /dev/null
+++ b/docs/netmiko/f5/index.html
@@ -0,0 +1,538 @@
+
+
+
+
+
+
+netmiko.f5 API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.f5.f5_tmsh_ssh import F5TmshSSH
+from netmiko.f5.f5_linux_ssh import F5LinuxSSH
+
+__all__ = ["F5TmshSSH", "F5LinuxSSH"]
+
+
+
+
+
+
+
+
+
+class F5LinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class F5LinuxSSH(LinuxSSH):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class F5TmshSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class F5TmshSSH(NoConfig, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+ def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+ def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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)
+
+Ancestors
+
+Methods
+
+
+def cleanup(self, command='exit')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """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 exit_tmsh(self)
+
+-
+
+
+Source code
+def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+
+
+def tmsh_mode(self, delay_factor=1.0)
+
+-
+
tmsh command is equivalent to config command on F5.
+
+Source code
+def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/flexvnf/flexvnf_ssh.html b/docs/netmiko/flexvnf/flexvnf_ssh.html
new file mode 100644
index 000000000..970cca267
--- /dev/null
+++ b/docs/netmiko/flexvnf/flexvnf_ssh.html
@@ -0,0 +1,878 @@
+
+
+
+
+
+
+netmiko.flexvnf.flexvnf_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.flexvnf.flexvnf_ssh
+
+
+
+Source code
+from typing import Optional, Any
+import re
+import time
+import warnings
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class FlexvnfSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+ def _strip_context_items(self, a_string: str) -> str:
+ """Strip FLEXVNF-specific output.
+
+ FLEXVNF will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"admin@lab-pg-dev-cp02v.*",
+ r"\[edit.*\]",
+ r"\[edit\]",
+ r"\[ok\]",
+ r"\[.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[0]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+
+
+
+
+
+
+
+
+class FlexvnfSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class FlexvnfSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+ def _strip_context_items(self, a_string: str) -> str:
+ """Strip FLEXVNF-specific output.
+
+ FLEXVNF will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"admin@lab-pg-dev-cp02v.*",
+ r"\[edit.*\]",
+ r"\[edit\]",
+ r"\[ok\]",
+ r"\[.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[0]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+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: str = "]", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def commit(self, confirm=False, confirm_delay=None, check=False, comment='', and_quit=False, read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration. Raise an error and return the failure
+if the commit fails.
+Automatically enters configuration mode
+default:
+command_string = commit
+check and (confirm or confirm_dely or comment):
+Exception
+confirm_delay and no confirm:
+Exception
+confirm:
+confirm_delay option
+comment option
+command_string = commit confirmed or commit confirmed
+check:
+command_string = commit check
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+
+
+def config_mode(self, config_command='configure', pattern='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def enter_cli_mode(self)
+
+-
+
Check if at shell prompt root@ and go into CLI.
+
+Source code
+def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+
+
+def exit_config_mode(self, exit_config='exit configuration-mode', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "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) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+
+
+def strip_prompt(self, *args, **kwargs)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/flexvnf/index.html b/docs/netmiko/flexvnf/index.html
new file mode 100644
index 000000000..6e6a94051
--- /dev/null
+++ b/docs/netmiko/flexvnf/index.html
@@ -0,0 +1,690 @@
+
+
+
+
+
+
+netmiko.flexvnf API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.flexvnf
+
+
+
+Source code
+from netmiko.flexvnf.flexvnf_ssh import FlexvnfSSH
+
+__all__ = ["FlexvnfSSH"]
+
+
+
+
+
+
+
+
+
+class FlexvnfSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class FlexvnfSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+ def _strip_context_items(self, a_string: str) -> str:
+ """Strip FLEXVNF-specific output.
+
+ FLEXVNF will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"admin@lab-pg-dev-cp02v.*",
+ r"\[edit.*\]",
+ r"\[edit\]",
+ r"\[ok\]",
+ r"\[.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[0]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+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: str = "]", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def commit(self, confirm=False, confirm_delay=None, check=False, comment='', and_quit=False, read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration. Raise an error and return the failure
+if the commit fails.
+Automatically enters configuration mode
+default:
+command_string = commit
+check and (confirm or confirm_dely or comment):
+Exception
+confirm_delay and no confirm:
+Exception
+confirm:
+confirm_delay option
+comment option
+command_string = commit confirmed or commit confirmed
+check:
+command_string = commit check
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+
+
+def config_mode(self, config_command='configure', pattern='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def enter_cli_mode(self)
+
+-
+
Check if at shell prompt root@ and go into CLI.
+
+Source code
+def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+
+
+def exit_config_mode(self, exit_config='exit configuration-mode', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "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) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+
+
+def strip_prompt(self, *args, **kwargs)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/fortinet/fortinet_ssh.html b/docs/netmiko/fortinet/fortinet_ssh.html
new file mode 100644
index 000000000..6354b95a9
--- /dev/null
+++ b/docs/netmiko/fortinet/fortinet_ssh.html
@@ -0,0 +1,552 @@
+
+
+
+
+
+
+netmiko.fortinet.fortinet_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.fortinet.fortinet_ssh
+
+
+
+Source code
+import paramiko
+import re
+from typing import Optional
+
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class FortinetSSH(NoConfig, CiscoSSHConnection):
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ paramiko_transport = getattr(paramiko, "Transport")
+ paramiko_transport._preferred_kex = (
+ "diffie-hellman-group14-sha1",
+ "diffie-hellman-group-exchange-sha1",
+ "diffie-hellman-group-exchange-sha256",
+ "diffie-hellman-group1-sha1",
+ )
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging is only available with specific roles so it may fail."""
+ check_command = "get system status | grep Virtual"
+ output = self._send_command_timing_str(check_command)
+ self.allow_disable_global = True
+ self.vdoms = False
+ self._output_mode = "more"
+
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
+ self.vdoms = True
+ vdom_additional_command = "config global"
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
+ if "Command fail" in output:
+ self.allow_disable_global = False
+ if self.remote_conn is not None:
+ self.remote_conn.close()
+ self.establish_connection(width=100, height=1000)
+
+ new_output = ""
+ if self.allow_disable_global:
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
+ # There is an extra 'end' required if in multi-vdoms are enabled
+ if self.vdoms:
+ disable_paging_commands.append("end")
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
+ # Should test output is valid
+ new_output = self.RETURN.join(outputlist)
+
+ return output + new_output
+
+ def _retrieve_output_mode(self) -> None:
+ """Save the state of the output mode so it can be reset at the end of the session."""
+ reg_mode = re.compile(r"output\s+:\s+(?P<mode>.*)\s+\n")
+ output = self._send_command_str("get system console")
+ result_mode_re = reg_mode.search(output)
+ if result_mode_re:
+ result_mode = result_mode_re.group("mode").strip()
+ if result_mode in ["more", "standard"]:
+ self._output_mode = result_mode
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Re-enable paging globally."""
+ if self.allow_disable_global:
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
+ if self.vdoms:
+ enable_paging_commands.insert(0, "config global")
+ # Should test output is valid
+ for command in enable_paging_commands:
+ self.send_command_timing(command)
+ return super().cleanup(command=command)
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class FortinetSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class FortinetSSH(NoConfig, CiscoSSHConnection):
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ paramiko_transport = getattr(paramiko, "Transport")
+ paramiko_transport._preferred_kex = (
+ "diffie-hellman-group14-sha1",
+ "diffie-hellman-group-exchange-sha1",
+ "diffie-hellman-group-exchange-sha256",
+ "diffie-hellman-group1-sha1",
+ )
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging is only available with specific roles so it may fail."""
+ check_command = "get system status | grep Virtual"
+ output = self._send_command_timing_str(check_command)
+ self.allow_disable_global = True
+ self.vdoms = False
+ self._output_mode = "more"
+
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
+ self.vdoms = True
+ vdom_additional_command = "config global"
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
+ if "Command fail" in output:
+ self.allow_disable_global = False
+ if self.remote_conn is not None:
+ self.remote_conn.close()
+ self.establish_connection(width=100, height=1000)
+
+ new_output = ""
+ if self.allow_disable_global:
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
+ # There is an extra 'end' required if in multi-vdoms are enabled
+ if self.vdoms:
+ disable_paging_commands.append("end")
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
+ # Should test output is valid
+ new_output = self.RETURN.join(outputlist)
+
+ return output + new_output
+
+ def _retrieve_output_mode(self) -> None:
+ """Save the state of the output mode so it can be reset at the end of the session."""
+ reg_mode = re.compile(r"output\s+:\s+(?P<mode>.*)\s+\n")
+ output = self._send_command_str("get system console")
+ result_mode_re = reg_mode.search(output)
+ if result_mode_re:
+ result_mode = result_mode_re.group("mode").strip()
+ if result_mode in ["more", "standard"]:
+ self._output_mode = result_mode
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Re-enable paging globally."""
+ if self.allow_disable_global:
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
+ if self.vdoms:
+ enable_paging_commands.insert(0, "config global")
+ # Should test output is valid
+ for command in enable_paging_commands:
+ self.send_command_timing(command)
+ return super().cleanup(command=command)
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def cleanup(self, command='exit')
+
+-
+
Re-enable paging globally.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """Re-enable paging globally."""
+ if self.allow_disable_global:
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
+ if self.vdoms:
+ enable_paging_commands.insert(0, "config global")
+ # Should test output is valid
+ for command in enable_paging_commands:
+ self.send_command_timing(command)
+ return super().cleanup(command=command)
+
+
+
+def disable_paging(self, command='terminal length 0', delay_factor=None, cmd_verify=True, pattern=None)
+
+-
+
Disable paging is only available with specific roles so it may fail.
+
+Source code
+def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+) -> str:
+ """Disable paging is only available with specific roles so it may fail."""
+ check_command = "get system status | grep Virtual"
+ output = self._send_command_timing_str(check_command)
+ self.allow_disable_global = True
+ self.vdoms = False
+ self._output_mode = "more"
+
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
+ self.vdoms = True
+ vdom_additional_command = "config global"
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
+ if "Command fail" in output:
+ self.allow_disable_global = False
+ if self.remote_conn is not None:
+ self.remote_conn.close()
+ self.establish_connection(width=100, height=1000)
+
+ new_output = ""
+ if self.allow_disable_global:
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
+ # There is an extra 'end' required if in multi-vdoms are enabled
+ if self.vdoms:
+ disable_paging_commands.append("end")
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
+ # Should test output is valid
+ new_output = self.RETURN.join(outputlist)
+
+ return output + new_output
+
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
+ self.disable_paging()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/fortinet/index.html b/docs/netmiko/fortinet/index.html
new file mode 100644
index 000000000..0a62e5097
--- /dev/null
+++ b/docs/netmiko/fortinet/index.html
@@ -0,0 +1,463 @@
+
+
+
+
+
+
+netmiko.fortinet API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.fortinet
+
+
+
+Source code
+from netmiko.fortinet.fortinet_ssh import FortinetSSH
+
+__all__ = ["FortinetSSH"]
+
+
+
+
+
+
+
+
+
+class FortinetSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class FortinetSSH(NoConfig, CiscoSSHConnection):
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ paramiko_transport = getattr(paramiko, "Transport")
+ paramiko_transport._preferred_kex = (
+ "diffie-hellman-group14-sha1",
+ "diffie-hellman-group-exchange-sha1",
+ "diffie-hellman-group-exchange-sha256",
+ "diffie-hellman-group1-sha1",
+ )
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging is only available with specific roles so it may fail."""
+ check_command = "get system status | grep Virtual"
+ output = self._send_command_timing_str(check_command)
+ self.allow_disable_global = True
+ self.vdoms = False
+ self._output_mode = "more"
+
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
+ self.vdoms = True
+ vdom_additional_command = "config global"
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
+ if "Command fail" in output:
+ self.allow_disable_global = False
+ if self.remote_conn is not None:
+ self.remote_conn.close()
+ self.establish_connection(width=100, height=1000)
+
+ new_output = ""
+ if self.allow_disable_global:
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
+ # There is an extra 'end' required if in multi-vdoms are enabled
+ if self.vdoms:
+ disable_paging_commands.append("end")
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
+ # Should test output is valid
+ new_output = self.RETURN.join(outputlist)
+
+ return output + new_output
+
+ def _retrieve_output_mode(self) -> None:
+ """Save the state of the output mode so it can be reset at the end of the session."""
+ reg_mode = re.compile(r"output\s+:\s+(?P<mode>.*)\s+\n")
+ output = self._send_command_str("get system console")
+ result_mode_re = reg_mode.search(output)
+ if result_mode_re:
+ result_mode = result_mode_re.group("mode").strip()
+ if result_mode in ["more", "standard"]:
+ self._output_mode = result_mode
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Re-enable paging globally."""
+ if self.allow_disable_global:
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
+ if self.vdoms:
+ enable_paging_commands.insert(0, "config global")
+ # Should test output is valid
+ for command in enable_paging_commands:
+ self.send_command_timing(command)
+ return super().cleanup(command=command)
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def cleanup(self, command='exit')
+
+-
+
Re-enable paging globally.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """Re-enable paging globally."""
+ if self.allow_disable_global:
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
+ if self.vdoms:
+ enable_paging_commands.insert(0, "config global")
+ # Should test output is valid
+ for command in enable_paging_commands:
+ self.send_command_timing(command)
+ return super().cleanup(command=command)
+
+
+
+def disable_paging(self, command='terminal length 0', delay_factor=None, cmd_verify=True, pattern=None)
+
+-
+
Disable paging is only available with specific roles so it may fail.
+
+Source code
+def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+) -> str:
+ """Disable paging is only available with specific roles so it may fail."""
+ check_command = "get system status | grep Virtual"
+ output = self._send_command_timing_str(check_command)
+ self.allow_disable_global = True
+ self.vdoms = False
+ self._output_mode = "more"
+
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
+ self.vdoms = True
+ vdom_additional_command = "config global"
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
+ if "Command fail" in output:
+ self.allow_disable_global = False
+ if self.remote_conn is not None:
+ self.remote_conn.close()
+ self.establish_connection(width=100, height=1000)
+
+ new_output = ""
+ if self.allow_disable_global:
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
+ # There is an extra 'end' required if in multi-vdoms are enabled
+ if self.vdoms:
+ disable_paging_commands.append("end")
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
+ # Should test output is valid
+ new_output = self.RETURN.join(outputlist)
+
+ return output + new_output
+
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
+ self.disable_paging()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/hp/hp_comware.html b/docs/netmiko/hp/hp_comware.html
new file mode 100644
index 000000000..8d615db8d
--- /dev/null
+++ b/docs/netmiko/hp/hp_comware.html
@@ -0,0 +1,1000 @@
+
+
+
+
+
+
+netmiko.hp.hp_comware API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.hp.hp_comware
+
+
+
+Source code
+import re
+from typing import Union, Sequence, TextIO, Any, Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class HPComwareBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # Comware doesn't have a way to set terminal width which breaks cmd_verify
+ global_cmd_verify = kwargs.get("global_cmd_verify")
+ if global_cmd_verify is None:
+ kwargs["global_cmd_verify"] = False
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # Comware can have a banner that prompts you to continue
+ # 'Press Y or ENTER to continue, N to exit.'
+ data = self._test_channel_read(pattern=r"to continue|[>\]]")
+ if "continue" in data:
+ self.write_channel("\n")
+ self._test_channel_read(pattern=r"[>\]]")
+
+ self.set_base_prompt()
+ command = self.RETURN + "screen-length disable"
+ self.disable_paging(command=command)
+
+ def config_mode(
+ self, config_command: str = "system-view", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit config mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"\]",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ read_timeout=read_timeout,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ strip_prompt=strip_prompt,
+ strip_command=strip_command,
+ config_mode_command=config_mode_command,
+ cmd_verify=cmd_verify,
+ enter_config_mode=enter_config_mode,
+ error_pattern=error_pattern,
+ terminator=terminator,
+ bypass_commands=bypass_commands,
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Comware
+ this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off leading character
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def enable(
+ self,
+ cmd: str = "system-view",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """enable mode on Comware is system-view."""
+ return self.config_mode(config_command=cmd)
+
+ def exit_enable_mode(self, exit_command: str = "return") -> str:
+ """enable mode on Comware is system-view."""
+ return self.exit_config_mode(exit_config=exit_command)
+
+ def check_enable_mode(self, check_string: str = "]") -> bool:
+ """enable mode on Comware is system-view."""
+ return self.check_config_mode(check_string=check_string)
+
+ def save_config(
+ self, cmd: str = "save force", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HPComwareSSH(HPComwareBase):
+ pass
+
+
+class HPComwareTelnet(HPComwareBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class HPComwareBase
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPComwareBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # Comware doesn't have a way to set terminal width which breaks cmd_verify
+ global_cmd_verify = kwargs.get("global_cmd_verify")
+ if global_cmd_verify is None:
+ kwargs["global_cmd_verify"] = False
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # Comware can have a banner that prompts you to continue
+ # 'Press Y or ENTER to continue, N to exit.'
+ data = self._test_channel_read(pattern=r"to continue|[>\]]")
+ if "continue" in data:
+ self.write_channel("\n")
+ self._test_channel_read(pattern=r"[>\]]")
+
+ self.set_base_prompt()
+ command = self.RETURN + "screen-length disable"
+ self.disable_paging(command=command)
+
+ def config_mode(
+ self, config_command: str = "system-view", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit config mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"\]",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ read_timeout=read_timeout,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ strip_prompt=strip_prompt,
+ strip_command=strip_command,
+ config_mode_command=config_mode_command,
+ cmd_verify=cmd_verify,
+ enter_config_mode=enter_config_mode,
+ error_pattern=error_pattern,
+ terminator=terminator,
+ bypass_commands=bypass_commands,
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Comware
+ this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off leading character
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def enable(
+ self,
+ cmd: str = "system-view",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """enable mode on Comware is system-view."""
+ return self.config_mode(config_command=cmd)
+
+ def exit_enable_mode(self, exit_command: str = "return") -> str:
+ """enable mode on Comware is system-view."""
+ return self.exit_config_mode(exit_config=exit_command)
+
+ def check_enable_mode(self, check_string: str = "]") -> bool:
+ """enable mode on Comware is system-view."""
+ return self.check_config_mode(check_string=check_string)
+
+ def save_config(
+ self, cmd: str = "save force", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=']', pattern='')
+
+-
+
Check whether device is in configuration mode. Return a boolean.
+
+Source code
+def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def check_enable_mode(self, check_string=']')
+
+-
+
enable mode on Comware is system-view.
+
+Source code
+def check_enable_mode(self, check_string: str = "]") -> bool:
+ """enable mode on Comware is system-view."""
+ return self.check_config_mode(check_string=check_string)
+
+
+
+def enable(self, cmd='system-view', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
enable mode on Comware is system-view.
+
+Source code
+def enable(
+ self,
+ cmd: str = "system-view",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """enable mode on Comware is system-view."""
+ return self.config_mode(config_command=cmd)
+
+
+
+def exit_config_mode(self, exit_config='return', pattern='>')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit config mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def exit_enable_mode(self, exit_command='return')
+
+-
+
enable mode on Comware is system-view.
+
+Source code
+def exit_enable_mode(self, exit_command: str = "return") -> str:
+ """enable mode on Comware is system-view."""
+ return self.exit_config_mode(exit_config=exit_command)
+
+
+
+def save_config(self, cmd='save force', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "save force", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """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) -> None:
+ """Prepare the session after the connection has been established."""
+ # Comware can have a banner that prompts you to continue
+ # 'Press Y or ENTER to continue, N to exit.'
+ data = self._test_channel_read(pattern=r"to continue|[>\]]")
+ if "continue" in data:
+ self.write_channel("\n")
+ self._test_channel_read(pattern=r"[>\]]")
+
+ self.set_base_prompt()
+ command = self.RETURN + "screen-length disable"
+ self.disable_paging(command=command)
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator=']', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt
+Used as delimiter for stripping of trailing prompt in output.
+Should be set to something that is general and applies in multiple contexts. For Comware
+this will be the router prompt with < > or [ ] stripped off.
+This will be set on logging in, but not when entering system-view
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Comware
+ this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off leading character
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+class HPComwareSSH
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPComwareSSH(HPComwareBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class HPComwareTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPComwareTelnet(HPComwareBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/hp/hp_procurve.html b/docs/netmiko/hp/hp_procurve.html
new file mode 100644
index 000000000..3b7d835fb
--- /dev/null
+++ b/docs/netmiko/hp/hp_procurve.html
@@ -0,0 +1,1105 @@
+
+
+
+
+
+
+netmiko.hp.hp_procurve API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.hp.hp_procurve
+
+
+
+Source code
+import re
+import time
+import socket
+from os import path
+from typing import Optional
+
+from paramiko import SSHClient
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+from netmiko.exceptions import ReadTimeout
+
+
+class HPProcurveBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ # HP output contains VT100 escape codes
+ self.ansi_escape_codes = True
+
+ # Procurve over SSH uses 'Press any key to continue'
+ data = self._test_channel_read(pattern=r"(any key to continue|[>#])")
+ if "any key to continue" in data:
+ self.write_channel(self.RETURN)
+ self._test_channel_read(pattern=r"[>#]")
+
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ command = self.RETURN + "no page"
+ self.disable_paging(command=command)
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ The pattern is needed as it is not in the parent class.
+
+ Not having this will make each check_config_mode() call take ~2 seconds.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ default_username: str = "manager",
+ ) -> str:
+ """Enter enable mode"""
+
+ if self.check_enable_mode():
+ return ""
+
+ output = ""
+ username_pattern = r"(username|login|user name)"
+ pwd_pattern = pattern
+ prompt_pattern = r"[>#]"
+ full_pattern = rf"(username|login|user name|{pwd_pattern}|{prompt_pattern})"
+
+ # Send the enable command
+ self.write_channel(cmd + self.RETURN)
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the username
+ if re.search(username_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(default_username + self.RETURN)
+ full_pattern = rf"{pwd_pattern}|{prompt_pattern})"
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the password
+ if re.search(pwd_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(self.secret + self.RETURN)
+ new_output = self.read_until_pattern(
+ prompt_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ output += new_output
+ log.debug(f"{output}")
+ self.clear_buffer()
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Gracefully exit the SSH session."""
+
+ # Exit configuration mode.
+ try:
+ if self.check_config_mode():
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # Terminate SSH/telnet session
+ self.write_channel(command + self.RETURN)
+
+ output = ""
+ for _ in range(10):
+
+ # The connection might be dead here.
+ try:
+ # "Do you want to log out"
+ # "Do you want to save the current"
+ pattern = r"Do you want.*"
+ new_output = self.read_until_pattern(pattern, read_timeout=1.5)
+ output += new_output
+
+ if "Do you want to log out" in new_output:
+ self.write_channel("y" + self.RETURN)
+ break
+ elif "Do you want to save the current" in new_output:
+ # Don't automatically save the config (user's responsibility)
+ self.write_channel("n" + self.RETURN)
+ except socket.error:
+ break
+ except ReadTimeout:
+ break
+ except Exception:
+ break
+
+ time.sleep(0.05)
+
+ # Set outside of loop
+ self._session_log_fin = True
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HPProcurveSSH(HPProcurveBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Allow passwordless authentication for HP devices being provisioned."""
+
+ # Create instance of SSHClient object. If no SSH keys and no password, then use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys and not self.password:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+
+class HPProcurveTelnet(HPProcurveBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+
+
+
+
+
+
+class HPProcurveBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPProcurveBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ # HP output contains VT100 escape codes
+ self.ansi_escape_codes = True
+
+ # Procurve over SSH uses 'Press any key to continue'
+ data = self._test_channel_read(pattern=r"(any key to continue|[>#])")
+ if "any key to continue" in data:
+ self.write_channel(self.RETURN)
+ self._test_channel_read(pattern=r"[>#]")
+
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ command = self.RETURN + "no page"
+ self.disable_paging(command=command)
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ The pattern is needed as it is not in the parent class.
+
+ Not having this will make each check_config_mode() call take ~2 seconds.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ default_username: str = "manager",
+ ) -> str:
+ """Enter enable mode"""
+
+ if self.check_enable_mode():
+ return ""
+
+ output = ""
+ username_pattern = r"(username|login|user name)"
+ pwd_pattern = pattern
+ prompt_pattern = r"[>#]"
+ full_pattern = rf"(username|login|user name|{pwd_pattern}|{prompt_pattern})"
+
+ # Send the enable command
+ self.write_channel(cmd + self.RETURN)
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the username
+ if re.search(username_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(default_username + self.RETURN)
+ full_pattern = rf"{pwd_pattern}|{prompt_pattern})"
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the password
+ if re.search(pwd_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(self.secret + self.RETURN)
+ new_output = self.read_until_pattern(
+ prompt_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ output += new_output
+ log.debug(f"{output}")
+ self.clear_buffer()
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Gracefully exit the SSH session."""
+
+ # Exit configuration mode.
+ try:
+ if self.check_config_mode():
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # Terminate SSH/telnet session
+ self.write_channel(command + self.RETURN)
+
+ output = ""
+ for _ in range(10):
+
+ # The connection might be dead here.
+ try:
+ # "Do you want to log out"
+ # "Do you want to save the current"
+ pattern = r"Do you want.*"
+ new_output = self.read_until_pattern(pattern, read_timeout=1.5)
+ output += new_output
+
+ if "Do you want to log out" in new_output:
+ self.write_channel("y" + self.RETURN)
+ break
+ elif "Do you want to save the current" in new_output:
+ # Don't automatically save the config (user's responsibility)
+ self.write_channel("n" + self.RETURN)
+ except socket.error:
+ break
+ except ReadTimeout:
+ break
+ except Exception:
+ break
+
+ time.sleep(0.05)
+
+ # Set outside of loop
+ self._session_log_fin = True
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=')#', pattern='[>#]')
+
+-
+
The pattern is needed as it is not in the parent class.
+Not having this will make each check_config_mode() call take ~2 seconds.
+
+Source code
+def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>#]"
+) -> bool:
+ """
+ The pattern is needed as it is not in the parent class.
+
+ Not having this will make each check_config_mode() call take ~2 seconds.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def enable(self, cmd='enable', pattern='password', enable_pattern=None, re_flags=, default_username='manager')
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ default_username: str = "manager",
+) -> str:
+ """Enter enable mode"""
+
+ if self.check_enable_mode():
+ return ""
+
+ output = ""
+ username_pattern = r"(username|login|user name)"
+ pwd_pattern = pattern
+ prompt_pattern = r"[>#]"
+ full_pattern = rf"(username|login|user name|{pwd_pattern}|{prompt_pattern})"
+
+ # Send the enable command
+ self.write_channel(cmd + self.RETURN)
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the username
+ if re.search(username_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(default_username + self.RETURN)
+ full_pattern = rf"{pwd_pattern}|{prompt_pattern})"
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the password
+ if re.search(pwd_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(self.secret + self.RETURN)
+ new_output = self.read_until_pattern(
+ prompt_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ output += new_output
+ log.debug(f"{output}")
+ self.clear_buffer()
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """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) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ # HP output contains VT100 escape codes
+ self.ansi_escape_codes = True
+
+ # Procurve over SSH uses 'Press any key to continue'
+ data = self._test_channel_read(pattern=r"(any key to continue|[>#])")
+ if "any key to continue" in data:
+ self.write_channel(self.RETURN)
+ self._test_channel_read(pattern=r"[>#]")
+
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ command = self.RETURN + "no page"
+ self.disable_paging(command=command)
+
+
+
+Inherited members
+
+
+
+class HPProcurveSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPProcurveSSH(HPProcurveBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Allow passwordless authentication for HP devices being provisioned."""
+
+ # Create instance of SSHClient object. If no SSH keys and no password, then use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys and not self.password:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class HPProcurveTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPProcurveTelnet(HPProcurveBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='(Login Name:|sername:)', pwd_pattern='assword', delay_factor=1.0, max_loops=60)
+
+-
+
Telnet login: can be username/password or just password.
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/hp/index.html b/docs/netmiko/hp/index.html
new file mode 100644
index 000000000..0087a4765
--- /dev/null
+++ b/docs/netmiko/hp/index.html
@@ -0,0 +1,846 @@
+
+
+
+
+
+
+netmiko.hp API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.hp.hp_procurve import HPProcurveSSH, HPProcurveTelnet
+from netmiko.hp.hp_comware import HPComwareSSH, HPComwareTelnet
+
+__all__ = ["HPProcurveSSH", "HPProcurveTelnet", "HPComwareSSH", "HPComwareTelnet"]
+
+
+
+
+
+
+
+
+
+class HPComwareSSH
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPComwareSSH(HPComwareBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class HPComwareTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPComwareTelnet(HPComwareBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+class HPProcurveSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPProcurveSSH(HPProcurveBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Allow passwordless authentication for HP devices being provisioned."""
+
+ # Create instance of SSHClient object. If no SSH keys and no password, then use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys and not self.password:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class HPProcurveTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HPProcurveTelnet(HPProcurveBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='(Login Name:|sername:)', pwd_pattern='assword', delay_factor=1.0, max_loops=60)
+
+-
+
Telnet login: can be username/password or just password.
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/huawei/huawei.html b/docs/netmiko/huawei/huawei.html
new file mode 100644
index 000000000..cbbc81653
--- /dev/null
+++ b/docs/netmiko/huawei/huawei.html
@@ -0,0 +1,1540 @@
+
+
+
+
+
+
+netmiko.huawei.huawei API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.huawei.huawei
+
+
+
+Source code
+from typing import Optional, Any
+import time
+import re
+import warnings
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.exceptions import NetmikoAuthenticationException
+from netmiko import log
+
+
+class HuaweiBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>\]]")
+ self.set_base_prompt()
+ self.disable_paging(command="screen-length 0 temporary")
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ return super().strip_ansi_escape_codes(output)
+
+ def config_mode(
+ self,
+ config_command: str = "system-view",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts.
+ For Huawei this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off any leading HRP_. characters for USGv5 HA
+ prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
+
+ # Strip off leading terminator
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ log.debug(f"prompt: {self.base_prompt}")
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = True, confirm_response: str = "y"
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HuaweiSSH(HuaweiBase):
+ """Huawei SSH driver."""
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+
+class HuaweiTelnet(HuaweiBase):
+ """Huawei Telnet driver."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+
+class HuaweiVrpv8SSH(HuaweiSSH):
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class HuaweiBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>\]]")
+ self.set_base_prompt()
+ self.disable_paging(command="screen-length 0 temporary")
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ return super().strip_ansi_escape_codes(output)
+
+ def config_mode(
+ self,
+ config_command: str = "system-view",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts.
+ For Huawei this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off any leading HRP_. characters for USGv5 HA
+ prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
+
+ # Strip off leading terminator
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ log.debug(f"prompt: {self.base_prompt}")
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = True, confirm_response: str = "y"
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string=']', pattern='')
+
+-
+
Checks whether in configuration mode. Returns a boolean.
+
+Source code
+def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def exit_config_mode(self, exit_config='return', pattern='>')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def save_config(self, cmd='save', confirm=True, confirm_response='y')
+
+-
+
Save Config for HuaweiSSH
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = True, confirm_response: str = "y"
+) -> str:
+ """Save Config for HuaweiSSH"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>\]]")
+ self.set_base_prompt()
+ self.disable_paging(command="screen-length 0 temporary")
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator=']', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt
+Used as delimiter for stripping of trailing prompt in output.
+Should be set to something that is general and applies in multiple contexts.
+For Huawei this will be the router prompt with < > or [ ] stripped off.
+This will be set on logging in, but not when entering system-view
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts.
+ For Huawei this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off any leading HRP_. characters for USGv5 HA
+ prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
+
+ # Strip off leading terminator
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ log.debug(f"prompt: {self.base_prompt}")
+ return self.base_prompt
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
Huawei does a strange thing where they add a space and then add ESC[1D
+to move the cursor to the left one.
+The extra space is problematic.
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ return super().strip_ansi_escape_codes(output)
+
+
+
+Inherited members
+
+
+
+class HuaweiSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiSSH(HuaweiBase):
+ """Huawei SSH driver."""
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Handle password change request by ignoring it
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+
+
+Inherited members
+
+
+
+class HuaweiTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiTelnet(HuaweiBase):
+ """Huawei Telnet driver."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+Ancestors
+
+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.0, max_loops=20)
+
+-
+
Telnet login for Huawei Devices
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+
+
+Inherited members
+
+
+
+class HuaweiVrpv8SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiVrpv8SSH(HuaweiSSH):
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/huawei/huawei_smartax.html b/docs/netmiko/huawei/huawei_smartax.html
new file mode 100644
index 000000000..7d61d143e
--- /dev/null
+++ b/docs/netmiko/huawei/huawei_smartax.html
@@ -0,0 +1,523 @@
+
+
+
+
+
+
+netmiko.huawei.huawei_smartax API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.huawei.huawei_smartax
+
+
+
+Source code
+import time
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko import log
+
+
+class HuaweiSmartAXSSH(CiscoBaseConnection):
+ """Supports Huawei SmartAX and OLT."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+ def _disable_smart_interaction(
+ self, command: str = "undo smart", delay_factor: float = 1.0
+ ) -> None:
+ """Disables the { <cr> } prompt to avoid having to sent a 2nd return after each command"""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_smart_interaction")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ if self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ output = self.read_until_prompt(read_entire_line=True)
+ else:
+ output = self.read_until_prompt(read_entire_line=True)
+ log.debug(f"{output}")
+ log.debug("Exiting disable_smart_interaction")
+
+ def disable_paging(
+ self,
+ command: str = "scroll",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string)
+
+ def exit_config_mode(
+ self, exit_config: str = "return", pattern: str = r"#.*"
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags, enable_pattern=enable_pattern
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class HuaweiSmartAXSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Supports Huawei SmartAX and OLT.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiSmartAXSSH(CiscoBaseConnection):
+ """Supports Huawei SmartAX and OLT."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+ def _disable_smart_interaction(
+ self, command: str = "undo smart", delay_factor: float = 1.0
+ ) -> None:
+ """Disables the { <cr> } prompt to avoid having to sent a 2nd return after each command"""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_smart_interaction")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ if self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ output = self.read_until_prompt(read_entire_line=True)
+ else:
+ output = self.read_until_prompt(read_entire_line=True)
+ log.debug(f"{output}")
+ log.debug("Exiting disable_smart_interaction")
+
+ def disable_paging(
+ self,
+ command: str = "scroll",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string)
+
+ def exit_config_mode(
+ self, exit_config: str = "return", pattern: str = r"#.*"
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags, enable_pattern=enable_pattern
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save', confirm=False, confirm_response='')
+
+-
+
Save Config for HuaweiSSH
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Save Config for HuaweiSSH"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
Huawei does a strange thing where they add a space and then add ESC[1D
+to move the cursor to the left one.
+The extra space is problematic.
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/huawei/index.html b/docs/netmiko/huawei/index.html
new file mode 100644
index 000000000..1cf1126ac
--- /dev/null
+++ b/docs/netmiko/huawei/index.html
@@ -0,0 +1,1271 @@
+
+
+
+
+
+
+netmiko.huawei API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.huawei.huawei import HuaweiSSH, HuaweiVrpv8SSH
+from netmiko.huawei.huawei import HuaweiTelnet
+from netmiko.huawei.huawei_smartax import HuaweiSmartAXSSH
+
+__all__ = ["HuaweiSmartAXSSH", "HuaweiSSH", "HuaweiVrpv8SSH", "HuaweiTelnet"]
+
+
+
+
+
+
+
+
+
+class HuaweiSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiSSH(HuaweiBase):
+ """Huawei SSH driver."""
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Handle password change request by ignoring it
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+
+
+Inherited members
+
+
+
+class HuaweiSmartAXSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Supports Huawei SmartAX and OLT.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiSmartAXSSH(CiscoBaseConnection):
+ """Supports Huawei SmartAX and OLT."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+ def _disable_smart_interaction(
+ self, command: str = "undo smart", delay_factor: float = 1.0
+ ) -> None:
+ """Disables the { <cr> } prompt to avoid having to sent a 2nd return after each command"""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_smart_interaction")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ if self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ output = self.read_until_prompt(read_entire_line=True)
+ else:
+ output = self.read_until_prompt(read_entire_line=True)
+ log.debug(f"{output}")
+ log.debug("Exiting disable_smart_interaction")
+
+ def disable_paging(
+ self,
+ command: str = "scroll",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string)
+
+ def exit_config_mode(
+ self, exit_config: str = "return", pattern: str = r"#.*"
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags, enable_pattern=enable_pattern
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save', confirm=False, confirm_response='')
+
+-
+
Save Config for HuaweiSSH
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Save Config for HuaweiSSH"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
Huawei does a strange thing where they add a space and then add ESC[1D
+to move the cursor to the left one.
+The extra space is problematic.
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+
+
+Inherited members
+
+
+
+class HuaweiTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiTelnet(HuaweiBase):
+ """Huawei Telnet driver."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+Ancestors
+
+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.0, max_loops=20)
+
+-
+
Telnet login for Huawei Devices
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+
+
+Inherited members
+
+
+
+class HuaweiVrpv8SSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Huawei SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class HuaweiVrpv8SSH(HuaweiSSH):
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/index.html b/docs/netmiko/index.html
new file mode 100644
index 000000000..cb3c19b2b
--- /dev/null
+++ b/docs/netmiko/index.html
@@ -0,0 +1,6481 @@
+
+
+
+
+
+
+netmiko API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+import logging
+
+# Logging configuration
+log = logging.getLogger(__name__) # noqa
+log.addHandler(logging.NullHandler()) # noqa
+
+from netmiko.ssh_dispatcher import ConnectHandler
+from netmiko.ssh_dispatcher import ConnLogOnly
+from netmiko.ssh_dispatcher import ConnUnify
+from netmiko.ssh_dispatcher import ssh_dispatcher
+from netmiko.ssh_dispatcher import redispatch
+from netmiko.ssh_dispatcher import platforms
+from netmiko.ssh_dispatcher import FileTransfer
+from netmiko.scp_handler import SCPConn
+from netmiko.cisco.cisco_ios import InLineTransfer
+from netmiko.exceptions import (
+ NetmikoTimeoutException,
+ NetMikoTimeoutException,
+)
+from netmiko.exceptions import (
+ NetmikoAuthenticationException,
+ NetMikoAuthenticationException,
+)
+from netmiko.exceptions import ConfigInvalidException
+from netmiko.exceptions import ReadException, ReadTimeout
+from netmiko.exceptions import NetmikoBaseException, ConnectionException
+from netmiko.ssh_autodetect import SSHDetect
+from netmiko.base_connection import BaseConnection
+from netmiko.scp_functions import file_transfer, progress_bar
+
+# Alternate naming
+Netmiko = ConnectHandler
+
+__version__ = "4.0.0"
+__all__ = (
+ "ConnectHandler",
+ "ConnLogOnly",
+ "ConnUnify",
+ "ssh_dispatcher",
+ "platforms",
+ "SCPConn",
+ "FileTransfer",
+ "NetmikoBaseException",
+ "ConnectionException",
+ "NetmikoTimeoutException",
+ "NetMikoTimeoutException",
+ "ConfigInvalidException",
+ "ReadException",
+ "ReadTimeout",
+ "NetmikoAuthenticationException",
+ "NetMikoAuthenticationException",
+ "InLineTransfer",
+ "redispatch",
+ "SSHDetect",
+ "BaseConnection",
+ "Netmiko",
+ "file_transfer",
+ "progress_bar",
+)
+
+# Cisco cntl-shift-six sequence
+CNTL_SHIFT_6 = chr(30)
+
+
+
+
+
+
+
+
+def ConnLogOnly(log_file='netmiko.log', log_level=None, log_format=None, **kwargs)
+
+-
+
Dispatcher function that will return either: netmiko_object or None
+Excluding errors in logging configuration should never generate an exception
+all errors should be logged.
+
+Source code
+def ConnLogOnly(
+ log_file: str = "netmiko.log",
+ log_level: Optional[int] = None,
+ log_format: Optional[str] = None,
+ **kwargs: Any,
+) -> Optional["BaseConnection"]:
+ """
+ Dispatcher function that will return either: netmiko_object or None
+
+ Excluding errors in logging configuration should never generate an exception
+ all errors should be logged.
+ """
+
+ import logging
+
+ if log_level is None:
+ log_level = logging.ERROR
+ if log_format is None:
+ log_format = "%(asctime)s %(levelname)s %(name)s %(message)s"
+
+ logging.basicConfig(filename=log_file, level=log_level, format=log_format)
+ logger = logging.getLogger(__name__)
+
+ try:
+ kwargs["auto_connect"] = False
+ net_connect = ConnectHandler(**kwargs)
+ hostname = net_connect.host
+ port = net_connect.port
+ device_type = net_connect.device_type
+
+ net_connect._open()
+ msg = f"Netmiko connection succesful to {hostname}:{port}"
+ logger.info(msg)
+ return net_connect
+ except NetmikoAuthenticationException as e:
+ msg = (
+ f"Authentication failure to: {hostname}:{port} ({device_type})\n\n{str(e)}"
+ )
+ logger.error(msg)
+ return None
+ except NetmikoTimeoutException as e:
+ if "DNS failure" in str(e):
+ msg = f"Device failed due to a DNS failure, hostname {hostname}"
+ elif "TCP connection to device failed" in str(e):
+ msg = f"Netmiko was unable to reach the provided host and port: {hostname}:{port}"
+ msg += f"\n\n{str(e)}"
+ logger.error(msg)
+ return None
+ except Exception as e:
+ msg = f"An unknown exception occurred during connection:\n\n{str(e)}"
+ logger.error(msg)
+ return None
+
+
+
+def ConnUnify(**kwargs)
+
+-
+
+
+Source code
+def ConnUnify(
+ **kwargs: Any,
+) -> "BaseConnection":
+
+ try:
+ kwargs["auto_connect"] = False
+ net_connect = ConnectHandler(**kwargs)
+ hostname = net_connect.host
+ port = net_connect.port
+ device_type = net_connect.device_type
+ general_msg = f"Connection failure to {hostname}:{port} ({device_type})\n\n"
+
+ net_connect._open()
+ return net_connect
+ except NetmikoAuthenticationException as e:
+ msg = general_msg + str(e)
+ raise ConnectionException(msg)
+ except NetmikoTimeoutException as e:
+ msg = general_msg + str(e)
+ raise ConnectionException(msg)
+ except Exception as e:
+ msg = f"An unknown exception occurred during connection:\n\n{str(e)}"
+ raise ConnectionException(msg)
+
+
+
+def ConnectHandler(*args, **kwargs)
+
+-
+
Factory function selects the proper class and creates object based on device_type.
+
+Source code
+def ConnectHandler(*args: Any, **kwargs: Any) -> "BaseConnection":
+ """Factory function selects the proper class and creates object based on device_type."""
+ device_type = kwargs["device_type"]
+ if device_type not in platforms:
+ if device_type is None:
+ msg_str = platforms_str
+ else:
+ msg_str = telnet_platforms_str if "telnet" in device_type else platforms_str
+ raise ValueError(
+ "Unsupported 'device_type' "
+ "currently supported platforms are: {}".format(msg_str)
+ )
+ ConnectionClass = ssh_dispatcher(device_type)
+ return ConnectionClass(*args, **kwargs)
+
+
+
+def FileTransfer(*args, **kwargs)
+
+-
+
Factory function selects the proper SCP class and creates object based on device_type.
+
+Source code
+def FileTransfer(*args: Any, **kwargs: Any) -> "BaseFileTransfer":
+ """Factory function selects the proper SCP class and creates object based on device_type."""
+ if len(args) >= 1:
+ device_type = args[0].device_type
+ else:
+ device_type = kwargs["ssh_conn"].device_type
+ if device_type not in scp_platforms:
+ raise ValueError(
+ "Unsupported SCP device_type: "
+ "currently supported platforms are: {}".format(scp_platforms_str)
+ )
+ FileTransferClass: Type["BaseFileTransfer"]
+ FileTransferClass = FILE_TRANSFER_MAP[device_type]
+ return FileTransferClass(*args, **kwargs)
+
+
+
+def Netmiko(*args, **kwargs)
+
+-
+
Factory function selects the proper class and creates object based on device_type.
+
+Source code
+def ConnectHandler(*args: Any, **kwargs: Any) -> "BaseConnection":
+ """Factory function selects the proper class and creates object based on device_type."""
+ device_type = kwargs["device_type"]
+ if device_type not in platforms:
+ if device_type is None:
+ msg_str = platforms_str
+ else:
+ msg_str = telnet_platforms_str if "telnet" in device_type else platforms_str
+ raise ValueError(
+ "Unsupported 'device_type' "
+ "currently supported platforms are: {}".format(msg_str)
+ )
+ ConnectionClass = ssh_dispatcher(device_type)
+ return ConnectionClass(*args, **kwargs)
+
+
+
+def file_transfer(ssh_conn, source_file, dest_file, file_system=None, direction='put', disable_md5=False, inline_transfer=False, overwrite_file=False, socket_timeout=10.0, progress=None, progress4=None, verify_file=None)
+
+-
+
Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
+inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
+return {
+'file_exists': boolean,
+'file_transferred': boolean,
+'file_verified': boolean,
+}
+
+Source code
+def file_transfer(
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ disable_md5: bool = False,
+ inline_transfer: bool = False,
+ overwrite_file: bool = False,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ verify_file: Optional[bool] = None,
+) -> Dict[str, bool]:
+ """Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
+
+ inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
+
+ return {
+ 'file_exists': boolean,
+ 'file_transferred': boolean,
+ 'file_verified': boolean,
+ }
+ """
+ transferred_and_verified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": True,
+ }
+ transferred_and_notverified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": False,
+ }
+ nottransferred_but_verified = {
+ "file_exists": True,
+ "file_transferred": False,
+ "file_verified": True,
+ }
+
+ if "cisco_ios" in ssh_conn.device_type or "cisco_xe" in ssh_conn.device_type:
+ cisco_ios = True
+ else:
+ cisco_ios = False
+ if not cisco_ios and inline_transfer:
+ raise ValueError("Inline Transfer only supported for Cisco IOS/Cisco IOS-XE")
+
+ # Replace disable_md5 argument with verify_file argument across time
+ if verify_file is None:
+ verify_file = not disable_md5
+
+ scp_args = {
+ "ssh_conn": ssh_conn,
+ "source_file": source_file,
+ "dest_file": dest_file,
+ "direction": direction,
+ "socket_timeout": socket_timeout,
+ "progress": progress,
+ "progress4": progress4,
+ }
+ if file_system is not None:
+ scp_args["file_system"] = file_system
+
+ TransferClass: Callable[..., BaseFileTransfer]
+ if inline_transfer:
+ TransferClass = InLineTransfer
+ else:
+ TransferClass = FileTransfer
+
+ with TransferClass(**scp_args) as scp_transfer:
+ if scp_transfer.check_file_exists():
+ if overwrite_file:
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ else:
+ # File exists, you can overwrite it, MD5 is wrong (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError(
+ "MD5 failure between source and destination files"
+ )
+ else:
+ # File exists, you can overwrite it, but MD5 not allowed (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ return transferred_and_notverified
+ else:
+ # File exists, but you can't overwrite it.
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ msg = "File already exists and overwrite_file is disabled"
+ raise ValueError(msg)
+ else:
+ verifyspace_and_transferfile(scp_transfer)
+ # File doesn't exist
+ if verify_file:
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError("MD5 failure between source and destination files")
+ else:
+ return transferred_and_notverified
+
+
+
+def progress_bar(filename, size, sent, peername=None)
+
+-
+
+
+Source code
+def progress_bar(
+ filename: AnyStr, size: int, sent: int, peername: Optional[str] = None
+) -> None:
+ max_width = 50
+ if isinstance(filename, bytes):
+ filename_str = filename.decode()
+ else:
+ filename_str = filename
+ clear_screen = chr(27) + "[2J"
+ terminating_char = "|"
+
+ # Percentage done
+ percent_complete = sent / size
+ percent_str = f"{percent_complete*100:.2f}%"
+ hash_count = int(percent_complete * max_width)
+ progress = hash_count * ">"
+
+ if peername is None:
+ header_msg = f"Transferring file: {filename_str}\n"
+ else:
+ header_msg = f"Transferring file to {peername}: {filename_str}\n"
+
+ msg = f"{progress:<50}{terminating_char:1} ({percent_str})"
+ print(clear_screen)
+ print(header_msg)
+ print(msg)
+
+
+
+def redispatch(obj, device_type, session_prep=True)
+
+-
+
Dynamically change Netmiko object's class to proper class.
+Generally used with terminal_server device_type when you need to redispatch after interacting
+with terminal server.
+
+Source code
+def redispatch(
+ obj: "BaseConnection", device_type: str, session_prep: bool = True
+) -> None:
+ """Dynamically change Netmiko object's class to proper class.
+ Generally used with terminal_server device_type when you need to redispatch after interacting
+ with terminal server.
+ """
+ new_class = ssh_dispatcher(device_type)
+ obj.device_type = device_type
+ obj.__class__ = new_class
+ if session_prep:
+ obj._try_session_preparation()
+
+
+
+def ssh_dispatcher(device_type)
+
+-
+
Select the class to be instantiated based on vendor/platform.
+
+Source code
+def ssh_dispatcher(device_type: str) -> Type["BaseConnection"]:
+ """Select the class to be instantiated based on vendor/platform."""
+ return CLASS_MAPPER[device_type]
+
+
+
+
+
+
+
+
+class BaseConnection
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class BaseConnection:
+ """
+ Defines vendor independent methods.
+
+ Otherwise method left as a stub method.
+ """
+
+ def __init__(
+ self,
+ ip: str = "",
+ host: str = "",
+ username: str = "",
+ password: Optional[str] = None,
+ secret: str = "",
+ port: Optional[int] = None,
+ device_type: str = "",
+ verbose: bool = False,
+ global_delay_factor: float = 1.0,
+ global_cmd_verify: Optional[bool] = None,
+ use_keys: bool = False,
+ key_file: Optional[str] = None,
+ pkey: Optional[paramiko.PKey] = None,
+ passphrase: Optional[str] = None,
+ disabled_algorithms: Optional[Dict[str, Any]] = None,
+ allow_agent: bool = False,
+ ssh_strict: bool = False,
+ system_host_keys: bool = False,
+ alt_host_keys: bool = False,
+ alt_key_file: str = "",
+ ssh_config_file: Optional[str] = None,
+ #
+ # Connect timeouts
+ # ssh-connect --> TCP conn (conn_timeout) --> SSH-banner (banner_timeout)
+ # --> Auth response (auth_timeout)
+ conn_timeout: int = 10,
+ # Timeout to wait for authentication response
+ auth_timeout: Optional[int] = None,
+ banner_timeout: int = 15, # Timeout to wait for the banner to be presented
+ # Other timeouts
+ blocking_timeout: int = 20, # Read blocking timeout
+ timeout: int = 100, # TCP connect timeout | overloaded to read-loop timeout
+ session_timeout: int = 60, # Used for locking/sharing the connection
+ read_timeout_override: Optional[float] = None,
+ keepalive: int = 0,
+ default_enter: Optional[str] = None,
+ response_return: Optional[str] = None,
+ serial_settings: Optional[Dict[str, Any]] = None,
+ fast_cli: bool = True,
+ _legacy_mode: bool = False,
+ session_log: Optional[SessionLog] = None,
+ session_log_record_writes: bool = False,
+ session_log_file_mode: str = "write",
+ allow_auto_change: bool = False,
+ encoding: str = "ascii",
+ sock: Optional[socket.socket] = None,
+ auto_connect: bool = True,
+ delay_factor_compat: bool = False,
+ ) -> None:
+ """
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default: \n).
+
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default: \n)
+
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+ """
+
+ self.remote_conn: Union[
+ None, telnetlib.Telnet, paramiko.Channel, serial.Serial
+ ] = None
+ # Does the platform support a configuration mode
+ self._config_mode = True
+ self._read_buffer = ""
+ self.delay_factor_compat = delay_factor_compat
+
+ self.TELNET_RETURN = "\r\n"
+ if default_enter is None:
+ if "telnet" not in device_type:
+ self.RETURN = "\n"
+ else:
+ self.RETURN = self.TELNET_RETURN
+ else:
+ self.RETURN = default_enter
+
+ # Line Separator in response lines
+ self.RESPONSE_RETURN = "\n" if response_return is None else response_return
+ if ip:
+ self.host = ip.strip()
+ elif host:
+ self.host = host.strip()
+ if not ip and not host and "serial" not in device_type:
+ raise ValueError("Either ip or host must be set")
+ if port is None:
+ if "telnet" in device_type:
+ port = 23
+ else:
+ port = 22
+ self.port = int(port)
+
+ self.username = username
+ self.password = password
+ self.secret = secret
+ self.device_type = device_type
+ self.ansi_escape_codes = False
+ self.verbose = verbose
+ self.auth_timeout = auth_timeout
+ self.banner_timeout = banner_timeout
+ self.blocking_timeout = blocking_timeout
+ self.conn_timeout = conn_timeout
+ self.session_timeout = session_timeout
+ self.timeout = timeout
+ self.read_timeout_override = read_timeout_override
+ self.keepalive = keepalive
+ self.allow_auto_change = allow_auto_change
+ self.encoding = encoding
+ self.sock = sock
+ self.fast_cli = fast_cli
+ self._legacy_mode = _legacy_mode
+ self.global_delay_factor = global_delay_factor
+ self.global_cmd_verify = global_cmd_verify
+ if self.fast_cli and self.global_delay_factor == 1:
+ self.global_delay_factor = 0.1
+ self.session_log = None
+ self._session_log_close = False
+
+ # prevent logging secret data
+ no_log = {}
+ if self.password:
+ no_log["password"] = self.password
+ if self.secret:
+ no_log["secret"] = self.secret
+ log.addFilter(SecretsFilter(no_log=no_log))
+
+ # Netmiko will close the session_log if we open the file
+ if session_log is not None:
+ if isinstance(session_log, str):
+ # If session_log is a string, open a file corresponding to string name.
+ self.session_log = SessionLog(
+ file_name=session_log,
+ file_mode=session_log_file_mode,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ self.session_log.open()
+ elif isinstance(session_log, io.BufferedIOBase):
+ # In-memory buffer or an already open file handle
+ self.session_log = SessionLog(
+ buffered_io=session_log,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ else:
+ raise ValueError(
+ "session_log must be a path to a file, a file handle, "
+ "or a BufferedIOBase subclass."
+ )
+
+ # Default values
+ self.serial_settings = {
+ "port": "COM1",
+ "baudrate": 9600,
+ "bytesize": serial.EIGHTBITS,
+ "parity": serial.PARITY_NONE,
+ "stopbits": serial.STOPBITS_ONE,
+ }
+ if serial_settings is None:
+ serial_settings = {}
+ self.serial_settings.update(serial_settings)
+
+ if "serial" in device_type:
+ self.host = "serial"
+ comm_port = self.serial_settings.pop("port")
+ # Get the proper comm port reference if a name was enterred
+ comm_port = check_serial_port(comm_port)
+ self.serial_settings.update({"port": comm_port})
+
+ # set in set_base_prompt method
+ self.base_prompt = ""
+ self._session_locker = Lock()
+
+ # determine if telnet or SSH
+ if "_telnet" in device_type:
+ self.protocol = "telnet"
+ self.password = password or ""
+ elif "_serial" in device_type:
+ self.protocol = "serial"
+ self.password = password or ""
+ else:
+ self.protocol = "ssh"
+
+ self.key_policy: paramiko.client.MissingHostKeyPolicy
+ if not ssh_strict:
+ self.key_policy = paramiko.AutoAddPolicy()
+ else:
+ self.key_policy = paramiko.RejectPolicy()
+
+ # Options for SSH host_keys
+ self.use_keys = use_keys
+ self.key_file = (
+ path.abspath(path.expanduser(key_file)) if key_file else None
+ )
+ self.pkey = pkey
+ self.passphrase = passphrase
+ self.allow_agent = allow_agent
+ self.system_host_keys = system_host_keys
+ self.alt_host_keys = alt_host_keys
+ self.alt_key_file = alt_key_file
+ self.disabled_algorithms = disabled_algorithms or {}
+
+ # For SSH proxy support
+ self.ssh_config_file = ssh_config_file
+
+ # Establish the remote connection
+ if auto_connect:
+ self._open()
+
+ def _open(self) -> None:
+ """Decouple connection creation from __init__ for mocking."""
+ self._modify_connection_params()
+ self.establish_connection()
+ self._try_session_preparation()
+
+ def __enter__(self) -> "BaseConnection":
+ """Establish a session using a Context Manager."""
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ """Gracefully close connection on Context Manager exit."""
+ self.disconnect()
+
+ def _modify_connection_params(self) -> None:
+ """Modify connection parameters prior to SSH connection."""
+ pass
+
+ def _timeout_exceeded(self, start: float, msg: str = "Timeout exceeded!") -> bool:
+ """Raise NetmikoTimeoutException if waiting too much in the serving queue.
+
+ :param start: Initial start time to see if session lock timeout has been exceeded
+ :type start: float (from time.time() call i.e. epoch time)
+
+ :param msg: Exception message if timeout was exceeded
+ :type msg: str
+ """
+ if not start:
+ # Must provide a comparison time
+ return False
+ if time.time() - start > self.session_timeout:
+ # session_timeout exceeded
+ raise NetmikoTimeoutException(msg)
+ return False
+
+ def _lock_netmiko_session(self, start: Optional[float] = None) -> bool:
+ """Try to acquire the Netmiko session lock. If not available, wait in the queue until
+ the channel is available again.
+
+ :param start: Initial start time to measure the session timeout
+ :type start: float (from time.time() call i.e. epoch time)
+ """
+ if not start:
+ start = time.time()
+ # Wait here until the SSH channel lock is acquired or until session_timeout exceeded
+ while not self._session_locker.acquire(False) and not self._timeout_exceeded(
+ start, "The netmiko channel is not available!"
+ ):
+ time.sleep(0.1)
+ return True
+
+ def _unlock_netmiko_session(self) -> None:
+ """
+ Release the channel at the end of the task.
+ """
+ if self._session_locker.locked():
+ self._session_locker.release()
+
+ def _autodetect_fs(self, cmd: str = "", pattern: str = "") -> str:
+ raise NotImplementedError
+
+ def _enter_shell(self) -> str:
+ raise NotImplementedError
+
+ def _return_cli(self) -> str:
+ raise NotImplementedError
+
+ @lock_channel
+ @log_writes
+ def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
+
+ :param out_data: data to be written to the channel
+ :type out_data: str
+ """
+ self.channel.write_channel(out_data)
+
+ def is_alive(self) -> bool:
+ """Returns a boolean flag with the state of the connection."""
+ null = chr(0)
+ if self.remote_conn is None:
+ log.error("Connection is not initialised, is_alive returns False")
+ return False
+ if self.protocol == "telnet":
+ try:
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
+ log.debug("Sending IAC + NOP")
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
+ except AttributeError:
+ return False
+ else:
+ # SSH
+ try:
+ # Try sending ASCII null byte to maintain the connection alive
+ log.debug("Sending the NULL byte")
+ self.write_channel(null)
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
+ except (socket.error, EOFError):
+ log.error("Unable to send", exc_info=True)
+ # If unable to send, we can tell for sure that the connection is unusable
+ return False
+ return False
+
+ @lock_channel
+ def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
+ return output
+
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
+
+ Will return string up to and including pattern.
+
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
+
+ :param pattern: Regular expression pattern used to identify that reading is done.
+
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
+
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
+ return output
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
+
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read data on the channel based on timing delays.
+
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
+
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
+
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
+ channel_data = ""
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+ # gather new output
+ if new_data:
+ channel_data += new_data
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
+ new_data = self.read_channel()
+ if not new_data:
+ break
+ else:
+ channel_data += new_data
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
+
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
+
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
+
+You can look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+ return channel_data
+
+ def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
+ if pattern:
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login. Can be username/password or just password.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param username_pattern: Pattern used to identify the username prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param max_loops: Controls the wait time in conjunction with the delay_factor
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+ def _try_session_preparation(self) -> None:
+ """
+ In case of an exception happening during `session_preparation()` Netmiko should
+ gracefully clean-up after itself. This might be challenging for library users
+ to do since they do not have a reference to the object. This is possibly related
+ to threads used in Paramiko.
+ """
+ try:
+ self.session_preparation()
+ except Exception:
+ self.disconnect()
+ raise
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some differences that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self._test_channel_read(pattern=r"some_pattern")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def _use_ssh_config(self, dict_arg: Dict[str, Any]) -> Dict[str, Any]:
+ """Update SSH connection parameters based on contents of SSH config file.
+
+ :param dict_arg: Dictionary of SSH connection parameters
+ """
+ connect_dict = dict_arg.copy()
+
+ # Use SSHConfig to generate source content.
+ assert self.ssh_config_file is not None
+ full_path = path.abspath(path.expanduser(self.ssh_config_file))
+ source: Union[paramiko.config.SSHConfigDict, Dict[str, Any]]
+ if path.exists(full_path):
+ ssh_config_instance = paramiko.SSHConfig()
+ with io.open(full_path, "rt", encoding="utf-8") as f:
+ ssh_config_instance.parse(f)
+ source = ssh_config_instance.lookup(self.host)
+ else:
+ source = {}
+
+ # Keys get normalized to lower-case
+ proxy: Optional[paramiko.proxy.ProxyCommand]
+ if "proxycommand" in source:
+ proxy = paramiko.ProxyCommand(source["proxycommand"])
+ elif "proxyjump" in source:
+ hops = list(reversed(source["proxyjump"].split(",")))
+ if len(hops) > 1:
+ raise ValueError(
+ "ProxyJump with more than one proxy server is not supported."
+ )
+ port = source.get("port", self.port)
+ host = source.get("hostname", self.host)
+ # -F {full_path} forces the continued use of the same SSH config file
+ cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0])
+ proxy = paramiko.ProxyCommand(cmd)
+ else:
+ proxy = None
+
+ # Only update 'hostname', 'sock', 'port', and 'username'
+ # For 'port' and 'username' only update if using object defaults
+ if connect_dict["port"] == 22:
+ connect_dict["port"] = int(source.get("port", self.port))
+ if connect_dict["username"] == "":
+ connect_dict["username"] = source.get("user", self.username)
+ if proxy:
+ connect_dict["sock"] = proxy
+ connect_dict["hostname"] = source.get("hostname", self.host)
+
+ return connect_dict
+
+ def _connect_params_dict(self) -> Dict[str, Any]:
+ """Generate dictionary of Paramiko connection parameters."""
+ conn_dict = {
+ "hostname": self.host,
+ "port": self.port,
+ "username": self.username,
+ "password": self.password,
+ "look_for_keys": self.use_keys,
+ "allow_agent": self.allow_agent,
+ "key_filename": self.key_file,
+ "pkey": self.pkey,
+ "passphrase": self.passphrase,
+ "disabled_algorithms": self.disabled_algorithms,
+ "timeout": self.conn_timeout,
+ "auth_timeout": self.auth_timeout,
+ "banner_timeout": self.banner_timeout,
+ "sock": self.sock,
+ }
+
+ # Check if using SSH 'config' file mainly for SSH proxy support
+ if self.ssh_config_file:
+ conn_dict = self._use_ssh_config(conn_dict)
+ return conn_dict
+
+ def _sanitize_output(
+ self,
+ output: str,
+ strip_command: bool = False,
+ command_string: Optional[str] = None,
+ strip_prompt: bool = False,
+ ) -> str:
+ """Strip out command echo and trailing router prompt."""
+ if strip_command and command_string:
+ command_string = self.normalize_linefeeds(command_string)
+ output = self.strip_command(command_string, output)
+ if strip_prompt:
+ output = self.strip_prompt(output)
+ return output
+
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
+ """Establish SSH connection to the network device
+
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
+
+ :param width: Specified width of the VT100 terminal window (default: 511)
+ :type width: int
+
+ :param height: Specified height of the VT100 terminal window (default: 1000)
+ :type height: int
+ """
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.telnet_login()
+ elif self.protocol == "serial":
+ self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.serial_login()
+ elif self.protocol == "ssh":
+ ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
+ self.remote_conn_pre = self._build_ssh_client()
+
+ # initiate SSH connection
+ try:
+ self.remote_conn_pre.connect(**ssh_connect_params)
+ except socket.error as conn_error:
+ self.paramiko_cleanup()
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
+ except paramiko.ssh_exception.AuthenticationException as auth_err:
+ self.paramiko_cleanup()
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ msg += self.RETURN + str(auth_err)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
+
+ if self.verbose:
+ print(f"SSH connection established to {self.host}:{self.port}")
+
+ # Use invoke_shell to establish an 'interactive session'
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
+
+ self.remote_conn.settimeout(self.blocking_timeout)
+ if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
+ self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
+ self.special_login_handler()
+ if self.verbose:
+ print("Interactive SSH session established")
+
+ return None
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Try to read the channel (generally post login) verify you receive data back.
+
+ :param count: the number of times to check the channel for data
+
+ :param pattern: Regular expression pattern used to determine end of channel read
+ """
+
+ def _increment_delay(
+ main_delay: float, increment: float = 1.1, maximum: int = 8
+ ) -> float:
+ """Increment sleep time to a maximum value."""
+ main_delay = main_delay * increment
+ if main_delay >= maximum:
+ main_delay = maximum
+ return main_delay
+
+ i = 0
+ delay_factor = self.select_delay_factor(delay_factor=0)
+
+ if pattern:
+ return self.read_until_pattern(pattern=pattern, read_timeout=20)
+
+ main_delay = delay_factor * 0.1
+ time.sleep(main_delay * 10)
+ new_data = ""
+ while i <= count:
+ new_data += self.read_channel_timing()
+ if new_data:
+ return new_data
+
+ self.write_channel(self.RETURN)
+ main_delay = _increment_delay(main_delay)
+ time.sleep(main_delay)
+ i += 1
+
+ raise NetmikoTimeoutException("Timed out waiting for data")
+
+ def _build_ssh_client(self) -> paramiko.SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ remote_conn_pre = paramiko.SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+ def select_delay_factor(self, delay_factor: float) -> float:
+ """
+ Choose the greater of delay_factor or self.global_delay_factor (default).
+ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+ """
+ if self.fast_cli:
+ if delay_factor and delay_factor <= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+ else:
+ if delay_factor >= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
+ pass
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Disable paging default to a Cisco CLI method.
+
+ :param command: Device command to disable pagination of output
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
+ log.debug("Exiting disable_paging")
+ return output
+
+ def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """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
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if not command:
+ return ""
+ command = self.normalize_cmd(command)
+ self.write_channel(command)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
+ return output
+
+ # 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),
+ reraise=True,
+ )
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Cisco
+ devices this will be set to router hostname (i.e. prompt without > or #).
+
+ This will be set on entering user exec or privileged exec on Cisco, but not when
+ entering/exiting config mode.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
+ """
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
+ if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
+ # Strip off trailing terminator
+ self.base_prompt = prompt[:-1]
+ return self.base_prompt
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ """Finds the current network device prompt, last line only.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
+ self.clear_buffer()
+ self.write_channel(self.RETURN)
+
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
+
+ # If multiple lines in the output take the last line
+ prompt = prompt.split(self.RESPONSE_RETURN)[-1]
+ prompt = prompt.strip()
+ self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
+ return prompt
+
+ def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """Read any data available in the channel."""
+
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+ def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+ @select_cmd_verify
+ def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a delay-based mechanism. Generally
+ used for show commands.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
+ """
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+ self.write_channel(command_string)
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+ def _send_command_timing_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command_timing` method that always returns a
+ string"""
+ output = self.send_command_timing(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ :param a_string: Returned string from device
+ :type a_string: str
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ if self.base_prompt in last_line:
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+ def _first_line_handler(self, data: str, search_pattern: str) -> Tuple[str, bool]:
+ """
+ In certain situations the first line will get repainted which causes a false
+ match on the terminating pattern.
+
+ Filter this out.
+
+ returns a tuple of (data, first_line_processed)
+
+ Where data is the original data potentially with the first line modified
+ and the first_line_processed is a flag indicating that we have handled the
+ first line.
+ """
+ try:
+ # First line is the echo line containing the command. In certain situations
+ # it gets repainted and needs filtered
+ lines = data.split(self.RETURN)
+ first_line = lines[0]
+ if BACKSPACE_CHAR in first_line:
+ pattern = search_pattern + r".*$"
+ first_line = re.sub(pattern, repl="", string=first_line)
+ lines[0] = first_line
+ data = self.RETURN.join(lines)
+ return (data, True)
+ except IndexError:
+ return (data, False)
+
+ def _prompt_handler(self, auto_find_prompt: bool) -> str:
+ if auto_find_prompt:
+ try:
+ prompt = self.find_prompt()
+ except ValueError:
+ prompt = self.base_prompt
+ else:
+ prompt = self.base_prompt
+ return re.escape(prompt.strip())
+
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+ used for show commands. By default this method will keep waiting to receive data until the
+ network device prompt is detected. The current network device prompt will be determined
+ automatically.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param expect_string: Regular expression pattern to use for determining end of output.
+ If left blank will default to being based on router prompt.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
+ """
+
+ # Time to delay in each read loop
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
+ else:
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
+ else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
+ search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
+
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+
+ # Start the clock
+ start_time = time.time()
+ self.write_channel(command_string)
+ new_data = ""
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
+ if new_data:
+ output += new_data
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
+ if re.search(search_pattern, output):
+ break
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+ def _send_command_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command` method that always returns a string"""
+ output = self.send_command(*args, **kwargs)
+ assert isinstance(output, str)
+ return output
+
+ def send_command_expect(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+ def _multiline_kwargs(self, **kwargs: Any) -> Dict[str, Any]:
+ strip_prompt = kwargs.get("strip_prompt", False)
+ kwargs["strip_prompt"] = strip_prompt
+ strip_command = kwargs.get("strip_command", False)
+ kwargs["strip_command"] = strip_command
+ return kwargs
+
+ def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """
+ commands should either be:
+
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
+
+ """
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+ def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+ ) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
+
+ @staticmethod
+ def strip_backspaces(output: str) -> str:
+ """Strip any backspace characters out of the output.
+
+ :param output: Output obtained from a remote network device.
+ :type output: str
+ """
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """
+ Strip command_string from output string
+
+ Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+
+ :param command_string: The command string sent to the device
+ :type command_string: str
+
+ :param output: The returned output as a result of the command string sent to the device
+ :type output: str
+ """
+ backspace_char = "\x08"
+
+ # Check for line wrap (remove backspaces)
+ if backspace_char in output:
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
+ output_lines = output.split(self.RESPONSE_RETURN)
+ new_output = output_lines[1:]
+ return self.RESPONSE_RETURN.join(new_output)
+ else:
+ # command_string isn't there; do nothing
+ return output
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
+
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+ """
+ newline = re.compile("(\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":
+ # Convert any remaining \r to \n
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
+
+ def normalize_cmd(self, command: str) -> str:
+ """Normalize CLI commands to have a single trailing newline.
+
+ :param command: Command that may require line feed to be normalized
+ :type command: str
+ """
+ command = command.rstrip()
+ command += self.RETURN
+ return command
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ """Check if in enable mode. Return boolean.
+
+ :param check_string: Identification of privilege mode from device
+ :type check_string: str
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode.
+
+ :param cmd: Device command to enter enable mode
+
+ :param pattern: pattern to search for indicating device is waiting for password
+
+ :param enable_pattern: pattern indicating you have entered enable mode
+
+ :param re_flags: Regular expression flags used in conjunction with pattern
+ """
+ output = ""
+ msg = (
+ "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:
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ """Exit enable mode.
+
+ :param exit_command: Command that exits the session from privileged mode
+ :type exit_command: str
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ output += self.read_until_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ :param check_string: Identification of configuration mode from the device
+ :type check_string: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ 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)
+ return check_string in output
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter into config_mode.
+
+ :param config_command: Configuration command to send to the device
+ :type config_command: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
+ """
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ """Exit from configuration mode.
+
+ :param exit_config: Command to exit configuration mode
+ :type exit_config: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel from a file.
+
+ The file is processed line-by-line and each command is sent down the
+ SSH channel.
+
+ **kwargs are passed to send_config_set method.
+
+ :param config_file: Path to configuration file to be sent to the device
+
+ :param kwargs: params to be sent to send_config_set method
+ """
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ """
+ Send configuration commands down the SSH channel.
+
+ config_commands is an iterable containing all of the configuration commands.
+ The commands will be executed one after the other.
+
+ Automatically exits/enters configuration mode.
+
+ :param config_commands: Multiple configuration commands to be sent to the device
+
+ :param exit_config_mode: Determines whether or not to exit config mode after complete
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Determines whether or not to strip the prompt
+
+ :param strip_command: Determines whether or not to strip the command
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+
+ :param config_mode_command: The command to enter into config mode
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
+ """
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
+ if config_commands is None:
+ return ""
+ elif isinstance(config_commands, str):
+ config_commands = (config_commands,)
+
+ if not hasattr(config_commands, "__iter__"):
+ raise ValueError("Invalid argument passed into send_config_set")
+
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
+ # Send config commands
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
+ log.debug(f"{output}")
+ return output
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Remove any ANSI (VT100) ESC codes from the output
+
+ http://en.wikipedia.org/wiki/ANSI_escape_code
+
+ Note: this does not capture ALL possible ANSI Escape Codes only the ones
+ I have encountered
+
+ Current codes that are filtered:
+ ESC = '\x1b' or chr(27)
+ ESC = is the escape character [^ in hex ('\x1b')
+ ESC[24;27H Position cursor
+ ESC[?25h Show the cursor
+ ESC[E Next line (HP does ESC-E)
+ ESC[K Erase line from cursor to the end of line
+ ESC[2K Erase entire line
+ ESC[1;24r Enable scrolling from start to row end
+ ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
+ ESC[?7l Disable line wrapping
+ ESC[2J Code erase display
+ ESC[00;32m Color Green (30 to 37 are different colors)
+ ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
+
+ HP ProCurve and Cisco SG300 require this (possible others).
+
+ :param string_buffer: The string to be processed to remove ANSI escape codes
+ :type string_buffer: str
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
+
+ output = string_buffer
+ for ansi_esc_code in code_set:
+ output = re.sub(ansi_esc_code, "", output)
+
+ # CODE_NEXT_LINE must substitute with return
+ output = re.sub(code_next_line, self.RETURN, output)
+
+ # Aruba and ProCurve switches can use code_insert_line for <enter>
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new <enter>
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
+
+ return output
+
+ def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
+ pass
+
+ def paramiko_cleanup(self) -> None:
+ """Cleanup Paramiko to try to gracefully handle SSH session ending."""
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
+ del self.remote_conn_pre
+
+ def disconnect(self) -> None:
+ """Try to gracefully close the session."""
+ try:
+ self.cleanup()
+ if self.protocol == "ssh":
+ self.paramiko_cleanup()
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ self.remote_conn.close()
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
+ self.remote_conn.close()
+ except Exception:
+ # There have been race conditions observed on disconnect.
+ pass
+ finally:
+ self.remote_conn_pre = None
+ self.remote_conn = None
+ if self.session_log:
+ self.session_log.close()
+
+ def commit(self) -> str:
+ """Commit method for platforms that support this."""
+ raise AttributeError("Network device does not support 'commit()' method")
+
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def run_ttp(
+ self,
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+ ) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
+Subclasses
+
+Static methods
+
+
+def strip_backspaces(output)
+
+-
+
Strip any backspace characters out of the output.
+:param output: Output obtained from a remote network device.
+:type output: str
+
+Source code
+@staticmethod
+def strip_backspaces(output: str) -> str:
+ """Strip any backspace characters out of the output.
+
+ :param output: Output obtained from a remote network device.
+ :type output: str
+ """
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
+
+
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+:param check_string: Identification of configuration mode from the device
+:type check_string: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not.
+
+ :param check_string: Identification of configuration mode from the device
+ :type check_string: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ 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)
+ return check_string in output
+
+
+
+def check_enable_mode(self, check_string='')
+
+-
+
Check if in enable mode. Return boolean.
+:param check_string: Identification of privilege mode from device
+:type check_string: str
+
+Source code
+def check_enable_mode(self, check_string: str = "") -> bool:
+ """Check if in enable mode. Return boolean.
+
+ :param check_string: Identification of privilege mode from device
+ :type check_string: str
+ """
+ self.write_channel(self.RETURN)
+ output = self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+
+
+def cleanup(self, command='')
+
+-
+
Logout of the session on the network device plus any additional cleanup.
+
+Source code
+def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
+ pass
+
+
+
+def clear_buffer(self, backoff=True, backoff_max=3.0, delay_factor=None)
+
+-
+
Read any data available in the channel.
+
+Source code
+def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """Read any data available in the channel."""
+
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+
+
+def command_echo_read(self, cmd, read_timeout)
+
+-
+
+
+Source code
+def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+
+
+def commit(self)
+
+-
+
Commit method for platforms that support this.
+
+Source code
+def commit(self) -> str:
+ """Commit method for platforms that support this."""
+ raise AttributeError("Network device does not support 'commit()' method")
+
+
+
+def config_mode(self, config_command='', pattern='', re_flags=0)
+
+-
+
Enter into config_mode.
+:param config_command: Configuration command to send to the device
+:type config_command: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+:param re_flags: Regular expression flags
+:type re_flags: RegexFlag
+
+Source code
+def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter into config_mode.
+
+ :param config_command: Configuration command to send to the device
+ :type config_command: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
+ """
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+
+
+def disable_paging(self, command='terminal length 0', delay_factor=None, cmd_verify=True, pattern=None)
+
+-
+
Disable paging default to a Cisco CLI method.
+:param command: Device command to disable pagination of output
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+) -> str:
+ """Disable paging default to a Cisco CLI method.
+
+ :param command: Device command to disable pagination of output
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
+ log.debug("Exiting disable_paging")
+ return output
+
+
+
+def disconnect(self)
+
+-
+
Try to gracefully close the session.
+
+Source code
+def disconnect(self) -> None:
+ """Try to gracefully close the session."""
+ try:
+ self.cleanup()
+ if self.protocol == "ssh":
+ self.paramiko_cleanup()
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ self.remote_conn.close()
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
+ self.remote_conn.close()
+ except Exception:
+ # There have been race conditions observed on disconnect.
+ pass
+ finally:
+ self.remote_conn_pre = None
+ self.remote_conn = None
+ if self.session_log:
+ self.session_log.close()
+
+
+
+def enable(self, cmd='', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
Enter enable mode.
+:param cmd: Device command to enter enable mode
+:param pattern: pattern to search for indicating device is waiting for password
+:param enable_pattern: pattern indicating you have entered enable mode
+:param re_flags: Regular expression flags used in conjunction with pattern
+
+Source code
+def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter enable mode.
+
+ :param cmd: Device command to enter enable mode
+
+ :param pattern: pattern to search for indicating device is waiting for password
+
+ :param enable_pattern: pattern indicating you have entered enable mode
+
+ :param re_flags: Regular expression flags used in conjunction with pattern
+ """
+ output = ""
+ msg = (
+ "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:
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ return output
+
+
+
+def establish_connection(self, width=511, height=1000)
+
+-
+
Establish SSH connection to the network device
+Timeout will generate a NetmikoTimeoutException
+Authentication failure will generate a NetmikoAuthenticationException
+:param width: Specified width of the VT100 terminal window (default: 511)
+:type width: int
+:param height: Specified height of the VT100 terminal window (default: 1000)
+:type height: int
+
+Source code
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
+ """Establish SSH connection to the network device
+
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
+
+ :param width: Specified width of the VT100 terminal window (default: 511)
+ :type width: int
+
+ :param height: Specified height of the VT100 terminal window (default: 1000)
+ :type height: int
+ """
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.telnet_login()
+ elif self.protocol == "serial":
+ self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
+ self.serial_login()
+ elif self.protocol == "ssh":
+ ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
+ self.remote_conn_pre = self._build_ssh_client()
+
+ # initiate SSH connection
+ try:
+ self.remote_conn_pre.connect(**ssh_connect_params)
+ except socket.error as conn_error:
+ self.paramiko_cleanup()
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
+ except paramiko.ssh_exception.AuthenticationException as auth_err:
+ self.paramiko_cleanup()
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ msg += self.RETURN + str(auth_err)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
+
+ if self.verbose:
+ print(f"SSH connection established to {self.host}:{self.port}")
+
+ # Use invoke_shell to establish an 'interactive session'
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
+
+ self.remote_conn.settimeout(self.blocking_timeout)
+ if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
+ self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
+ self.special_login_handler()
+ if self.verbose:
+ print("Interactive SSH session established")
+
+ return None
+
+
+
+def exit_config_mode(self, exit_config='', pattern='')
+
+-
+
Exit from configuration mode.
+:param exit_config: Command to exit configuration mode
+:type exit_config: str
+:param pattern: Pattern to terminate reading of channel
+:type pattern: str
+
+Source code
+def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ """Exit from configuration mode.
+
+ :param exit_config: Command to exit configuration mode
+ :type exit_config: str
+
+ :param pattern: Pattern to terminate reading of channel
+ :type pattern: str
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+
+
+def exit_enable_mode(self, exit_command='')
+
+-
+
Exit enable mode.
+:param exit_command: Command that exits the session from privileged mode
+:type exit_command: str
+
+Source code
+def exit_enable_mode(self, exit_command: str = "") -> str:
+ """Exit enable mode.
+
+ :param exit_command: Command that exits the session from privileged mode
+ :type exit_command: str
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ output += self.read_until_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+
+
+def find_prompt(self, delay_factor=1.0, pattern=None)
+
+-
+
Finds the current network device prompt, last line only.
+:param delay_factor: See init: global_delay_factor
+:type delay_factor: int
+:param pattern: Regular expression pattern to determine whether prompt is valid
+
+Source code
+def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+) -> str:
+ """Finds the current network device prompt, last line only.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
+ self.clear_buffer()
+ self.write_channel(self.RETURN)
+
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
+ prompt = self.read_channel().strip()
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
+
+ # If multiple lines in the output take the last line
+ prompt = prompt.split(self.RESPONSE_RETURN)[-1]
+ prompt = prompt.strip()
+ self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
+ return prompt
+
+
+
+def is_alive(self)
+
+-
+
Returns a boolean flag with the state of the connection.
+
+Source code
+def is_alive(self) -> bool:
+ """Returns a boolean flag with the state of the connection."""
+ null = chr(0)
+ if self.remote_conn is None:
+ log.error("Connection is not initialised, is_alive returns False")
+ return False
+ if self.protocol == "telnet":
+ try:
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
+ log.debug("Sending IAC + NOP")
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
+ except AttributeError:
+ return False
+ else:
+ # SSH
+ try:
+ # Try sending ASCII null byte to maintain the connection alive
+ log.debug("Sending the NULL byte")
+ self.write_channel(null)
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
+ except (socket.error, EOFError):
+ log.error("Unable to send", exc_info=True)
+ # If unable to send, we can tell for sure that the connection is unusable
+ return False
+ return False
+
+
+
+def normalize_cmd(self, command)
+
+-
+
Normalize CLI commands to have a single trailing newline.
+:param command: Command that may require line feed to be normalized
+:type command: str
+
+Source code
+def normalize_cmd(self, command: str) -> str:
+ """Normalize CLI commands to have a single trailing newline.
+
+ :param command: Command that may require line feed to be normalized
+ :type command: str
+ """
+ command = command.rstrip()
+ command += self.RETURN
+ return command
+
+
+
+def normalize_linefeeds(self, a_string)
+
+-
+
Convert `
+,
+,
+to
+.`
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+
+
+Source code
+def normalize_linefeeds(self, a_string: str) -> str:
+ """Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
+
+ :param a_string: A string that may have non-normalized line feeds
+ i.e. output returned from device, or a device prompt
+ :type a_string: str
+ """
+ newline = re.compile("(\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":
+ # Convert any remaining \r to \n
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
+
+
+
+def paramiko_cleanup(self)
+
+-
+
Cleanup Paramiko to try to gracefully handle SSH session ending.
+
+Source code
+def paramiko_cleanup(self) -> None:
+ """Cleanup Paramiko to try to gracefully handle SSH session ending."""
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
+ del self.remote_conn_pre
+
+
+
+def read_channel(self)
+
+-
+
Generic handler that will read all the data from given channel.
+
+Source code
+@lock_channel
+def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
+ return output
+
+
+
+def read_channel_timing(self, last_read=2.0, read_timeout=120.0, delay_factor=None, max_loops=None)
+
+-
+
Read data on the channel based on timing delays.
+General pattern is keep reading until no new data is read.
+Once no new data is read wait last_read amount of time (one last read).
+As long as no new data, then return data.
+read_timeout is an absolute timer for how long to keep reading (which presupposes
+we are still getting new data).
+Setting read_timeout to zero will cause read_channel_timing to never expire based
+on an absolute timeout. It will only complete based on timeout based on their being
+no new data.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read data on the channel based on timing delays.
+
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
+
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
+
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
+ channel_data = ""
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+ # gather new output
+ if new_data:
+ channel_data += new_data
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
+ new_data = self.read_channel()
+ if not new_data:
+ break
+ else:
+ channel_data += new_data
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
+
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
+
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
+
+You can look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+ return channel_data
+
+
+
+def read_until_pattern(self, pattern='', read_timeout=10.0, re_flags=0, max_loops=None)
+
+-
+
Read channel until pattern is detected.
+Will return string up to and including pattern.
+Returns ReadTimeout if pattern not detected in read_timeout seconds.
+:param pattern: Regular expression pattern used to identify that reading is done.
+:param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+reading indefinitely until pattern is detected.
+:param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
+
+ Will return string up to and including pattern.
+
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
+
+ :param pattern: Regular expression pattern used to identify that reading is done.
+
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
+
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
+ return output
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
+
+
+
+def read_until_prompt(self, read_timeout=10.0, read_entire_line=False, re_flags=0, max_loops=None)
+
+-
+
Read channel up to and including self.base_prompt.
+
+Source code
+def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+
+
+def read_until_prompt_or_pattern(self, pattern='', read_timeout=10.0, read_entire_line=False, re_flags=0, max_loops=None)
+
+-
+
Read until either self.base_prompt or pattern is detected.
+
+Source code
+def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
+ if pattern:
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+
+
+def run_ttp(self, template, res_kwargs=None, **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
+:param res_kwargs: **res_kwargs arguments to pass to TTP result method
+:param kwargs: any other **kwargs to use for TTP object instantiation
+TTP template must have inputs defined together with below parameters.
+:param method: name of Netmiko connection object method to call, default send_command
+:param kwargs: Netmiko connection object method arguments
+:param commands: list of commands to collect
+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: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
+
+
+def save_config(self, cmd='', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def select_delay_factor(self, delay_factor)
+
+-
+
Choose the greater of delay_factor or self.global_delay_factor (default).
+In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+:param delay_factor: See init: global_delay_factor
+:type delay_factor: int
+
+Source code
+def select_delay_factor(self, delay_factor: float) -> float:
+ """
+ Choose the greater of delay_factor or self.global_delay_factor (default).
+ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
+
+ :param delay_factor: See __init__: global_delay_factor
+ :type delay_factor: int
+ """
+ if self.fast_cli:
+ if delay_factor and delay_factor <= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+ else:
+ if delay_factor >= self.global_delay_factor:
+ return delay_factor
+ else:
+ return self.global_delay_factor
+
+
+
+def send_command(self, command_string, expect_string=None, read_timeout=10.0, delay_factor=None, max_loops=None, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=True)
+
+-
+
Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+used for show commands. By default this method will keep waiting to receive data until the
+network device prompt is detected. The current network device prompt will be determined
+automatically.
+:param command_string: The command to be executed on the remote device.
+:param expect_string: Regular expression pattern to use for determining end of output.
+If left blank will default to being based on router prompt.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Remove the trailing router prompt from the output (default: True).
+:param strip_command: Remove the echo of the command from the output (default: True).
+:param normalize: Ensure the proper enter is sent at end of command (default: True).
+:param use_textfsm: Process command output through TextFSM template (default: False).
+:param textfsm_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_ttp: Process command output through TTP template (default: False).
+:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_genie: Process command output through PyATS/Genie parser (default: False).
+:param cmd_verify: Verify command echo before proceeding (default: True).
+
+Source code
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a pattern-based mechanism. Generally
+ used for show commands. By default this method will keep waiting to receive data until the
+ network device prompt is detected. The current network device prompt will be determined
+ automatically.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param expect_string: Regular expression pattern to use for determining end of output.
+ If left blank will default to being based on router prompt.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
+ """
+
+ # Time to delay in each read loop
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
+ else:
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
+ else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
+ search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
+
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+
+ # Start the clock
+ start_time = time.time()
+ self.write_channel(command_string)
+ new_data = ""
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
+ if new_data:
+ output += new_data
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
+ if re.search(search_pattern, output):
+ break
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+
+
+def send_command_expect(self, *args, **kwargs)
+
+-
+
Support previous name of send_command method.
+
+Source code
+def send_command_expect(
+ self, *args: Any, **kwargs: Any
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+
+
+def send_command_timing(self, command_string, last_read=2.0, read_timeout=120.0, delay_factor=None, max_loops=None, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=False)
+
+-
+
Execute command_string on the SSH channel using a delay-based mechanism. Generally
+used for show commands.
+:param command_string: The command to be executed on the remote device.
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Remove the trailing router prompt from the output (default: True).
+:param strip_command: Remove the echo of the command from the output (default: True).
+:param normalize: Ensure the proper enter is sent at end of command (default: True).
+:param use_textfsm: Process command output through TextFSM template (default: False).
+:param textfsm_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_ttp: Process command output through TTP template (default: False).
+:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:param use_genie: Process command output through PyATS/Genie parser (default: False).
+:param cmd_verify: Verify command echo before proceeding (default: False).
+
+Source code
+@select_cmd_verify
+def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Execute command_string on the SSH channel using a delay-based mechanism. Generally
+ used for show commands.
+
+ :param command_string: The command to be executed on the remote device.
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Remove the trailing router prompt from the output (default: True).
+
+ :param strip_command: Remove the echo of the command from the output (default: True).
+
+ :param normalize: Ensure the proper enter is sent at end of command (default: True).
+
+ :param use_textfsm: Process command output through TextFSM template (default: False).
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
+ """
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
+ if normalize:
+ command_string = self.normalize_cmd(command_string)
+ self.write_channel(command_string)
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+
+
+def send_config_from_file(self, config_file, **kwargs)
+
+-
+
Send configuration commands down the SSH channel from a file.
+The file is processed line-by-line and each command is sent down the
+SSH channel.
+**kwargs are passed to send_config_set method.
+:param config_file: Path to configuration file to be sent to the device
+:param kwargs: params to be sent to send_config_set method
+
+Source code
+def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+) -> str:
+ """
+ Send configuration commands down the SSH channel from a file.
+
+ The file is processed line-by-line and each command is sent down the
+ SSH channel.
+
+ **kwargs are passed to send_config_set method.
+
+ :param config_file: Path to configuration file to be sent to the device
+
+ :param kwargs: params to be sent to send_config_set method
+ """
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+
+
+def send_config_set(self, config_commands=None, *, exit_config_mode=True, read_timeout=None, delay_factor=None, max_loops=None, strip_prompt=False, strip_command=False, config_mode_command=None, cmd_verify=True, enter_config_mode=True, error_pattern='', terminator='#', bypass_commands=None)
+
+-
+
Send configuration commands down the SSH channel.
+config_commands is an iterable containing all of the configuration commands.
+The commands will be executed one after the other.
+Automatically exits/enters configuration mode.
+:param config_commands: Multiple configuration commands to be sent to the device
+:param exit_config_mode: Determines whether or not to exit config mode after complete
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+:param strip_prompt: Determines whether or not to strip the prompt
+:param strip_command: Determines whether or not to strip the command
+:param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+:param config_mode_command: The command to enter into config mode
+:param cmd_verify: Whether or not to verify command echo for each command in config_set
+:param enter_config_mode: Do you enter config mode before sending config commands
+:param error_pattern: Regular expression pattern to detect config errors in the
+output.
+:param terminator: Regular expression pattern to use as an alternate terminator in certain
+situations.
+:param bypass_commands: Regular expression pattern indicating configuration commands
+where cmd_verify is automatically disabled.
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+) -> str:
+ """
+ Send configuration commands down the SSH channel.
+
+ config_commands is an iterable containing all of the configuration commands.
+ The commands will be executed one after the other.
+
+ Automatically exits/enters configuration mode.
+
+ :param config_commands: Multiple configuration commands to be sent to the device
+
+ :param exit_config_mode: Determines whether or not to exit config mode after complete
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param strip_prompt: Determines whether or not to strip the prompt
+
+ :param strip_command: Determines whether or not to strip the command
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
+
+ :param config_mode_command: The command to enter into config mode
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
+ """
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
+ if config_commands is None:
+ return ""
+ elif isinstance(config_commands, str):
+ config_commands = (config_commands,)
+
+ if not hasattr(config_commands, "__iter__"):
+ raise ValueError("Invalid argument passed into send_config_set")
+
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
+ # Send config commands
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
+ log.debug(f"{output}")
+ return output
+
+
+
+def send_multiline(self, commands, multiline=True, **kwargs)
+
+-
+
commands should either be:
+commands = [[cmd1, expect1], [cmd2, expect2], …]]
+Or
+commands = [cmd1, cmd2, cmd3, …]
+Any expect_string that is a null-string will use pattern based on
+device's prompt (unless expect_string argument is passed in via
+kwargs.
+
+Source code
+def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+) -> str:
+ """
+ commands should either be:
+
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
+
+ """
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+
+
+def send_multiline_timing(self, commands, multiline=True, **kwargs)
+
+-
+
+
+Source code
+def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
+
+
+
+def serial_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='>\\s*$', username_pattern='(?:[Uu]ser:|sername|ogin)', pwd_pattern='assword', delay_factor=1.0, max_loops=20)
+
+-
+
+
+Source code
+def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established
+This method handles some differences that occur between various devices
+early on in the session.
+In general, it should include:
+self._test_channel_read(pattern=r"some_pattern")
+self.set_base_prompt()
+self.set_terminal_width()
+self.disable_paging()
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established
+
+ This method handles some differences that occur between various devices
+ early on in the session.
+
+ In general, it should include:
+ self._test_channel_read(pattern=r"some_pattern")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='#', alt_prompt_terminator='>', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt
+Used as delimiter for stripping of trailing prompt in output.
+Should be set to something that is general and applies in multiple contexts. For Cisco
+devices this will be set to router hostname (i.e. prompt without > or #).
+This will be set on entering user exec or privileged exec on Cisco, but not when
+entering/exiting config mode.
+:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+:param delay_factor: See init: global_delay_factor
+:param pattern: Regular expression pattern to search for in find_prompt() call
+
+Source code
+@retry(
+ 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: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Cisco
+ devices this will be set to router hostname (i.e. prompt without > or #).
+
+ This will be set on entering user exec or privileged exec on Cisco, but not when
+ entering/exiting config mode.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
+ """
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
+ if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
+ # Strip off trailing terminator
+ self.base_prompt = prompt[:-1]
+ return self.base_prompt
+
+
+
+def set_terminal_width(self, command='', delay_factor=None, cmd_verify=False, pattern=None)
+
+-
+
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
+:param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+) -> str:
+ """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
+
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if not command:
+ return ""
+ command = self.normalize_cmd(command)
+ self.write_channel(command)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
+ return output
+
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Handler for devices like WLC, Extreme ERS that throw up characters prior to login.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
+ pass
+
+
+
+def strip_ansi_escape_codes(self, string_buffer)
+
+-
+
Remove any ANSI (VT100) ESC codes from the output
+http://en.wikipedia.org/wiki/ANSI_escape_code
+Note: this does not capture ALL possible ANSI Escape Codes only the ones
+I have encountered
+Current codes that are filtered:
+ESC = '' or chr(27)
+ESC = is the escape character [^ in hex ('')
+ESC[24;27H
+Position cursor
+ESC[?25h
+Show the cursor
+ESC[E
+Next line (HP does ESC-E)
+ESC[K
+Erase line from cursor to the end of line
+ESC[2K
+Erase entire line
+ESC[1;24r
+Enable scrolling from start to row end
+ESC[?6l
+Reset mode screen with options 640 x 200 monochrome (graphics)
+ESC[?7l
+Disable line wrapping
+ESC[2J
+Code erase display
+ESC[00;32m
+Color Green (30 to 37 are different colors)
+ESC[6n
+Get cursor position
+ESC[1D
+Move cursor position leftward by x characters (1 in this case)
+ESC[9999B
+Move cursor down N-lines (very large value is attempt to move to the
+very bottom of the screen).
+HP ProCurve and Cisco SG300 require this (possible others).
+:param string_buffer: The string to be processed to remove ANSI escape codes
+:type string_buffer: str
+
+Source code
+def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Remove any ANSI (VT100) ESC codes from the output
+
+ http://en.wikipedia.org/wiki/ANSI_escape_code
+
+ Note: this does not capture ALL possible ANSI Escape Codes only the ones
+ I have encountered
+
+ Current codes that are filtered:
+ ESC = '\x1b' or chr(27)
+ ESC = is the escape character [^ in hex ('\x1b')
+ ESC[24;27H Position cursor
+ ESC[?25h Show the cursor
+ ESC[E Next line (HP does ESC-E)
+ ESC[K Erase line from cursor to the end of line
+ ESC[2K Erase entire line
+ ESC[1;24r Enable scrolling from start to row end
+ ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
+ ESC[?7l Disable line wrapping
+ ESC[2J Code erase display
+ ESC[00;32m Color Green (30 to 37 are different colors)
+ ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
+
+ HP ProCurve and Cisco SG300 require this (possible others).
+
+ :param string_buffer: The string to be processed to remove ANSI escape codes
+ :type string_buffer: str
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
+
+ output = string_buffer
+ for ansi_esc_code in code_set:
+ output = re.sub(ansi_esc_code, "", output)
+
+ # CODE_NEXT_LINE must substitute with return
+ output = re.sub(code_next_line, self.RETURN, output)
+
+ # Aruba and ProCurve switches can use code_insert_line for <enter>
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new <enter>
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
+
+ return output
+
+
+
+def strip_command(self, command_string, output)
+
+-
+
Strip command_string from output string
+Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+:param command_string: The command string sent to the device
+:type command_string: str
+:param output: The returned output as a result of the command string sent to the device
+:type output: str
+
+Source code
+def strip_command(self, command_string: str, output: str) -> str:
+ """
+ Strip command_string from output string
+
+ Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
+
+ :param command_string: The command string sent to the device
+ :type command_string: str
+
+ :param output: The returned output as a result of the command string sent to the device
+ :type output: str
+ """
+ backspace_char = "\x08"
+
+ # Check for line wrap (remove backspaces)
+ if backspace_char in output:
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
+ output_lines = output.split(self.RESPONSE_RETURN)
+ new_output = output_lines[1:]
+ return self.RESPONSE_RETURN.join(new_output)
+ else:
+ # command_string isn't there; do nothing
+ return output
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+:param a_string: Returned string from device
+:type a_string: str
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ :param a_string: Returned string from device
+ :type a_string: str
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ if self.base_prompt in last_line:
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ else:
+ return a_string
+
+
+
+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.0, max_loops=20)
+
+-
+
Telnet login. Can be username/password or just password.
+:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+:param username_pattern: Pattern used to identify the username prompt
+:param delay_factor: See init: global_delay_factor
+:param max_loops: Controls the wait time in conjunction with the delay_factor
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """Telnet login. Can be username/password or just password.
+
+ :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
+
+ :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
+
+ :param username_pattern: Pattern used to identify the username prompt
+
+ :param delay_factor: See __init__: global_delay_factor
+
+ :param max_loops: Controls the wait time in conjunction with the delay_factor
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+
+
+def write_channel(self, out_data)
+
+-
+
Generic method that will write data out the channel.
+:param out_data: data to be written to the channel
+:type out_data: str
+
+Source code
+@lock_channel
+@log_writes
+def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
+
+ :param out_data: data to be written to the channel
+ :type out_data: str
+ """
+ self.channel.write_channel(out_data)
+
+
+
+
+
+class ConfigInvalidException
+(*args, **kwargs)
+
+-
+
Exception raised for invalid configuration error.
+
+Source code
+class ConfigInvalidException(NetmikoBaseException):
+ """Exception raised for invalid configuration error."""
+
+ pass
+
+Ancestors
+
+
+
+class ConnectionException
+(*args, **kwargs)
+
+-
+
Generic exception indicating the connection failed.
+
+Source code
+class ConnectionException(NetmikoBaseException):
+ """Generic exception indicating the connection failed."""
+
+ pass
+
+Ancestors
+
+
+
+class InLineTransfer
+(ssh_conn, source_file='', dest_file='', file_system=None, direction='put', source_config=None, socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Use TCL on Cisco IOS to directly transfer file.
+
+Source code
+class InLineTransfer(CiscoIosFileTransfer):
+ """Use TCL on Cisco IOS to directly transfer file."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str = "",
+ dest_file: str = "",
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ source_config: Optional[str] = None,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+
+ if not dest_file:
+ raise ValueError(
+ "Destination file must be specified for InlineTransfer operations."
+ )
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for InLineTransfer")
+
+ if source_file and source_config:
+ msg = "Invalid call to InLineTransfer both source_file and source_config specified."
+ raise ValueError(msg)
+ if direction != "put":
+ raise ValueError("Only put operation supported by InLineTransfer.")
+
+ if progress is not None or progress4 is not None:
+ raise NotImplementedError(
+ "Progress bar is not supported on inline transfers."
+ )
+ else:
+ self.progress = progress
+ self.progress4 = progress4
+
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ if source_file:
+ self.source_config = None
+ self.source_md5 = self.file_md5(source_file)
+ self.file_size = os.stat(source_file).st_size
+ elif source_config:
+ self.source_config = source_config
+ self.source_md5 = self.config_md5(source_config)
+ self.file_size = len(source_config.encode("UTF-8"))
+ self.dest_file = dest_file
+ self.direction = direction
+
+ if not file_system:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ self.file_system = file_system
+
+ self.socket_timeout = socket_timeout
+
+ @staticmethod
+ def _read_file(file_name: str) -> str:
+ with io.open(file_name, "rt", encoding="utf-8") as f:
+ return f.read()
+
+ @staticmethod
+ def _tcl_newline_rationalize(tcl_string: str) -> str:
+ r"""
+ When using put inside a TCL {} section the newline is considered a new TCL
+ statement and causes a missing curly-brace message. Convert "\n" to "\r". TCL
+ will convert the "\r" to a "\n" i.e. you will see a "\n" inside the file on the
+ Cisco IOS device.
+ """
+ NEWLINE = r"\n"
+ CARRIAGE_RETURN = r"\r"
+ tmp_string = re.sub(NEWLINE, CARRIAGE_RETURN, tcl_string)
+ if re.search(r"[{}]", tmp_string):
+ msg = "Curly brace detected in string; TCL requires this be escaped."
+ raise ValueError(msg)
+ return tmp_string
+
+ def __enter__(self) -> "InLineTransfer":
+ self._enter_tcl_mode()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ self._exit_tcl_mode()
+
+ def _enter_tcl_mode(self) -> str:
+ TCL_ENTER = "tclsh"
+ cmd_failed = ['Translating "tclsh"', "% Unknown command", "% Bad IP address"]
+ output = self.ssh_ctl_chan._send_command_str(
+ TCL_ENTER,
+ expect_string=r"\(tcl\)#",
+ strip_prompt=False,
+ strip_command=False,
+ )
+ for pattern in cmd_failed:
+ if pattern in output:
+ raise ValueError(f"Failed to enter tclsh mode on router: {output}")
+ return output
+
+ def _exit_tcl_mode(self) -> str:
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel("\r")
+ time.sleep(1)
+ output = self.ssh_ctl_chan.read_channel()
+ if "(tcl)" in output:
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+ time.sleep(1)
+ output += self.ssh_ctl_chan.read_channel()
+ return output
+
+ def establish_scp_conn(self) -> None:
+ raise NotImplementedError
+
+ def close_scp_chan(self) -> None:
+ raise NotImplementedError
+
+ def local_space_available(self) -> bool:
+ raise NotImplementedError
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def put_file(self) -> None:
+ curlybrace = r"{"
+ TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(
+ self.file_system, self.dest_file, curlybrace
+ )
+ TCL_FILECMD_EXIT = "}"
+
+ if self.source_file:
+ file_contents = self._read_file(self.source_file)
+ elif self.source_config:
+ file_contents = self.source_config
+ file_contents = self._tcl_newline_rationalize(file_contents)
+
+ # Try to remove any existing data
+ self.ssh_ctl_chan.clear_buffer()
+
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_ENTER)
+ time.sleep(0.25)
+ self.ssh_ctl_chan.write_channel(file_contents)
+ self.ssh_ctl_chan.write_channel(TCL_FILECMD_EXIT + "\r")
+
+ # This operation can be slow (depends on the size of the file)
+ read_timeout = 100
+ sleep_time = 4
+ if self.file_size >= 2500:
+ read_timeout = 300
+ sleep_time = 12
+ elif self.file_size >= 7500:
+ read_timeout = 600
+ sleep_time = 25
+
+ # Initial delay
+ time.sleep(sleep_time)
+
+ # File paste and TCL_FILECMD_exit should be indicated by "router(tcl)#"
+ output = self.ssh_ctl_chan.read_until_pattern(
+ pattern=r"\(tcl\).*$", re_flags=re.M, read_timeout=read_timeout
+ )
+
+ # The file doesn't write until tclquit
+ TCL_EXIT = "tclquit"
+ self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
+
+ time.sleep(1)
+ # Read all data remaining from the TCLSH session
+ pattern = rf"tclquit.*{self.ssh_ctl_chan.base_prompt}.*$"
+ re_flags = re.DOTALL | re.M
+ output += self.ssh_ctl_chan.read_until_pattern(
+ pattern=pattern, re_flags=re_flags, read_timeout=read_timeout
+ )
+ return None
+
+ def get_file(self) -> None:
+ raise NotImplementedError
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def config_md5(self, source_config)
+
+-
+
Compute MD5 hash of text.
+
+Source code
+def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+def file_md5(self, file_name, add_newline=False)
+
+-
+
Compute MD5 hash of file.
+
+Source code
+def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
+ file_contents = self._read_file(file_name)
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+
+
+Inherited members
+
+
+
+class NetMikoAuthenticationException
+(*args, **kwargs)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetMikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoAuthenticationException
+(*args, **kwargs)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoBaseException
+(*args, **kwargs)
+
+-
+
General base exception except for exceptions that inherit from Paramiko.
+
+Source code
+class NetmikoBaseException(Exception):
+ """General base exception except for exceptions that inherit from Paramiko."""
+
+ pass
+
+Ancestors
+
+- builtins.Exception
+- builtins.BaseException
+
+Subclasses
+
+
+
+class NetmikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class ReadException
+(*args, **kwargs)
+
+-
+
General exception indicating an error occurred during a Netmiko read operation.
+
+Source code
+class ReadException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+Ancestors
+
+Subclasses
+
+
+
+class ReadTimeout
+(*args, **kwargs)
+
+-
+
General exception indicating an error occurred during a Netmiko read operation.
+
+Source code
+class ReadTimeout(ReadException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+Ancestors
+
+
+
+class SCPConn
+(ssh_conn, socket_timeout=10.0, progress=None, progress4=None)
+
+-
+
Establish a secure copy channel to the remote network device.
+Must close the SCP connection to get the file to write to the remote filesystem
+
+Source code
+class SCPConn(object):
+ """
+ Establish a secure copy channel to the remote network device.
+
+ Must close the SCP connection to get the file to write to the remote filesystem
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+ self.establish_scp_conn()
+
+ def establish_scp_conn(self) -> None:
+ """Establish the secure copy connection."""
+ ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
+ self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
+ self.scp_conn.connect(**ssh_connect_params)
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+ def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP (for backwards compatibility)."""
+ self.scp_client.put(source_file, dest_file)
+
+ def scp_get_file(self, source_file: str, dest_file: str) -> None:
+ """Get file using SCP."""
+ self.scp_client.get(source_file, dest_file)
+
+ def scp_put_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP."""
+ self.scp_client.put(source_file, dest_file)
+
+ def close(self) -> None:
+ """Close the SCP connection."""
+ self.scp_conn.close()
+
+Methods
+
+
+def close(self)
+
+-
+
Close the SCP connection.
+
+Source code
+def close(self) -> None:
+ """Close the SCP connection."""
+ self.scp_conn.close()
+
+
+
+def establish_scp_conn(self)
+
+-
+
Establish the secure copy connection.
+
+Source code
+def establish_scp_conn(self) -> None:
+ """Establish the secure copy connection."""
+ ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
+ self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
+ self.scp_conn.connect(**ssh_connect_params)
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+
+
+def scp_get_file(self, source_file, dest_file)
+
+-
+
+
+Source code
+def scp_get_file(self, source_file: str, dest_file: str) -> None:
+ """Get file using SCP."""
+ self.scp_client.get(source_file, dest_file)
+
+
+
+def scp_put_file(self, source_file, dest_file)
+
+-
+
+
+Source code
+def scp_put_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP."""
+ self.scp_client.put(source_file, dest_file)
+
+
+
+def scp_transfer_file(self, source_file, dest_file)
+
+-
+
Put file using SCP (for backwards compatibility).
+
+Source code
+def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP (for backwards compatibility)."""
+ self.scp_client.put(source_file, dest_file)
+
+
+
+
+
+class SSHDetect
+(*args, **kwargs)
+
+-
+
The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
+Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
+all.
+Parameters
+
+*args : list
+- The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+*kwargs : dict
+- The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+
+Attributes
+
+connection : TerminalServerSSH
+- A basic connection to the remote SSH end.
+potential_matches : dict
+- Dict of (device_type, accuracy) that is populated through an interaction with the
+remote end.
+
+Methods
+autodetect()
+Try to determine the device type.
+Constructor of the SSHDetect class
+
+Source code
+class SSHDetect(object):
+ """
+ The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
+ Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
+ all.
+
+ Parameters
+ ----------
+ *args : list
+ The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+ *kwargs : dict
+ The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+
+ Attributes
+ ----------
+ connection : netmiko.terminal_server.TerminalServerSSH
+ A basic connection to the remote SSH end.
+ potential_matches: dict
+ Dict of (device_type, accuracy) that is populated through an interaction with the
+ remote end.
+
+ Methods
+ -------
+ autodetect()
+ Try to determine the device type.
+ """
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """
+ Constructor of the SSHDetect class
+ """
+ if kwargs["device_type"] != "autodetect":
+ raise ValueError("The connection device_type must be 'autodetect'")
+ # Always set cmd_verify to False for autodetect
+ kwargs["global_cmd_verify"] = False
+ self.connection = ConnectHandler(*args, **kwargs)
+ # Call the _test_channel_read() in base to clear initial data
+ output = BaseConnection._test_channel_read(self.connection)
+ self.initial_buffer = output
+ self.potential_matches: Dict[str, int] = {}
+ self._results_cache: Dict[str, str] = {}
+
+ def autodetect(self) -> Union[str, None]:
+ """
+ Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+
+ 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:
+ tmp_dict = autodetect_dict.copy()
+ call_method = tmp_dict.pop("dispatch")
+ assert isinstance(call_method, str)
+ autodetect_method = getattr(self, call_method)
+ accuracy = autodetect_method(**tmp_dict)
+ if accuracy:
+ self.potential_matches[device_type] = accuracy
+ if accuracy >= 99: # Stop the loop as we are sure of our match
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ if not self.potential_matches:
+ self.connection.disconnect()
+ return None
+
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ def _send_command(self, cmd: str = "") -> str:
+ """
+ Handle reading/writing channel directly. It is also sanitizing the output received.
+
+ Parameters
+ ----------
+ cmd : str, optional
+ The command to send to the remote device (default : "", just send a new line)
+
+ Returns
+ -------
+ output : str
+ The output from the command sent
+ """
+ self.connection.write_channel(cmd + "\n")
+ time.sleep(1)
+ output = self.connection.read_channel_timing()
+ output = self.connection.strip_backspaces(output)
+ return output
+
+ def _send_command_wrapper(self, cmd: str) -> str:
+ """
+ Send command to the remote device with a caching feature to avoid sending the same command
+ twice based on the SSH_MAPPER_BASE dict cmd key.
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+
+ Returns
+ -------
+ response : str
+ The response from the remote device.
+ """
+ cached_results = self._results_cache.get(cmd)
+ if not cached_results:
+ response = self._send_command(cmd)
+ self._results_cache[cmd] = response
+ return response
+ else:
+ return cached_results
+
+ def _autodetect_remote_version(
+ self,
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ **kwargs: Any
+ ) -> int:
+ """
+ Method to try auto-detect the device type, by matching a regular expression on the reported
+ remote version of the SSH server.
+
+ Parameters
+ ----------
+ search_patterns : list
+ A list of regular expression to look for in the reported remote SSH version
+ (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [r"^$"]
+
+ if not search_patterns:
+ return 0
+
+ try:
+ remote_conn = self.connection.remote_conn
+ assert isinstance(remote_conn, paramiko.Channel)
+ assert remote_conn.transport is not None
+ remote_version = remote_conn.transport.remote_version
+ for pattern in invalid_responses:
+ match = re.search(pattern, remote_version, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, remote_version, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+ def _autodetect_std(
+ self,
+ cmd: str = "",
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ ) -> int:
+ """
+ Standard method to try to auto-detect the device type. This method will be called for each
+ device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
+ command and match some regular expression from the ouput for each entry in SSH_MAPPER_BASE
+ ('cmd' and 'search_pattern' keys).
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+ search_patterns : list
+ A list of regular expression to look for in the command's output (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [
+ r"% Invalid input detected",
+ r"syntax error, expecting",
+ r"Error: Unrecognized command",
+ r"%Error",
+ r"command not found",
+ r"Syntax Error: unexpected argument",
+ r"% Unrecognized command found at",
+ ]
+ if not cmd or not search_patterns:
+ return 0
+ try:
+ # _send_command_wrapper will use already cached results if available
+ response = self._send_command_wrapper(cmd)
+ # Look for error conditions in output
+ for pattern in invalid_responses:
+ match = re.search(pattern, response, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, response, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+Methods
+
+
+def autodetect(self)
+
+-
+
Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+Returns
+
+best_match : str or None
+- The device type that is currently the best to use to interact with the device
+
+
+Source code
+def autodetect(self) -> Union[str, None]:
+ """
+ Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+
+ 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:
+ tmp_dict = autodetect_dict.copy()
+ call_method = tmp_dict.pop("dispatch")
+ assert isinstance(call_method, str)
+ autodetect_method = getattr(self, call_method)
+ accuracy = autodetect_method(**tmp_dict)
+ if accuracy:
+ self.potential_matches[device_type] = accuracy
+ if accuracy >= 99: # Stop the loop as we are sure of our match
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ if not self.potential_matches:
+ self.connection.disconnect()
+ return None
+
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ self.connection.disconnect()
+ return best_match[0][0]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ipinfusion/index.html b/docs/netmiko/ipinfusion/index.html
new file mode 100644
index 000000000..c8ee4b2e3
--- /dev/null
+++ b/docs/netmiko/ipinfusion/index.html
@@ -0,0 +1,464 @@
+
+
+
+
+
+
+netmiko.ipinfusion API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ipinfusion
+
+
+
+Source code
+from netmiko.ipinfusion.ipinfusion_ocnos import (
+ IpInfusionOcNOSSSH,
+ IpInfusionOcNOSTelnet,
+)
+
+__all__ = ["IpInfusionOcNOSSSH", "IpInfusionOcNOSTelnet"]
+
+
+
+
+
+
+
+
+
+class IpInfusionOcNOSSSH
+(*args, **kwargs)
+
+-
+
IP Infusion OcNOS SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class IpInfusionOcNOSSSH(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class IpInfusionOcNOSTelnet
+(*args, **kwargs)
+
+-
+
IP Infusion OcNOS
+Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class IpInfusionOcNOSTelnet(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS Telnet driver."""
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ For all telnet options, re-implement the default telnetlib behaviour
+ and refuse to handle any options. If the server expresses interest in
+ 'terminal type' option, then reply back with 'xterm' terminal type.
+ """
+ if command == DO and option == TTYPE:
+ tsocket.sendall(IAC + WILL + TTYPE)
+ tsocket.sendall(IAC + SB + TTYPE + b"\0" + b"xterm" + IAC + SE)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(?:user:|sername|login|user name)",
+ pwd_pattern: str = r"assword:",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ # set callback function to handle telnet options.
+ assert self.remote_conn is not None
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ipinfusion/ipinfusion_ocnos.html b/docs/netmiko/ipinfusion/ipinfusion_ocnos.html
new file mode 100644
index 000000000..119f40c20
--- /dev/null
+++ b/docs/netmiko/ipinfusion/ipinfusion_ocnos.html
@@ -0,0 +1,743 @@
+
+
+
+
+
+
+netmiko.ipinfusion.ipinfusion_ocnos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ipinfusion.ipinfusion_ocnos
+
+
+
+Source code
+import time
+from typing import Any
+from socket import socket
+
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, TTYPE, Telnet
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class IpInfusionOcNOSBase(CiscoBaseConnection):
+ """Common Methods for IP Infusion OcNOS support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using write command"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class IpInfusionOcNOSSSH(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS SSH driver."""
+
+ pass
+
+
+class IpInfusionOcNOSTelnet(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS Telnet driver."""
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ For all telnet options, re-implement the default telnetlib behaviour
+ and refuse to handle any options. If the server expresses interest in
+ 'terminal type' option, then reply back with 'xterm' terminal type.
+ """
+ if command == DO and option == TTYPE:
+ tsocket.sendall(IAC + WILL + TTYPE)
+ tsocket.sendall(IAC + SB + TTYPE + b"\0" + b"xterm" + IAC + SE)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(?:user:|sername|login|user name)",
+ pwd_pattern: str = r"assword:",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ # set callback function to handle telnet options.
+ assert self.remote_conn is not None
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+
+
+
+
+
+
+class IpInfusionOcNOSBase
+(*args, **kwargs)
+
+-
+
Common Methods for IP Infusion OcNOS support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class IpInfusionOcNOSBase(CiscoBaseConnection):
+ """Common Methods for IP Infusion OcNOS support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using write command"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write', confirm=False, confirm_response='')
+
+-
+
Saves Config Using write command
+
+Source code
+def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config Using write command"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class IpInfusionOcNOSSSH
+(*args, **kwargs)
+
+-
+
IP Infusion OcNOS SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class IpInfusionOcNOSSSH(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class IpInfusionOcNOSTelnet
+(*args, **kwargs)
+
+-
+
IP Infusion OcNOS
+Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class IpInfusionOcNOSTelnet(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS Telnet driver."""
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ For all telnet options, re-implement the default telnetlib behaviour
+ and refuse to handle any options. If the server expresses interest in
+ 'terminal type' option, then reply back with 'xterm' terminal type.
+ """
+ if command == DO and option == TTYPE:
+ tsocket.sendall(IAC + WILL + TTYPE)
+ tsocket.sendall(IAC + SB + TTYPE + b"\0" + b"xterm" + IAC + SE)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(?:user:|sername|login|user name)",
+ pwd_pattern: str = r"assword:",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ # set callback function to handle telnet options.
+ assert self.remote_conn is not None
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/juniper/index.html b/docs/netmiko/juniper/index.html
new file mode 100644
index 000000000..a30c96b48
--- /dev/null
+++ b/docs/netmiko/juniper/index.html
@@ -0,0 +1,768 @@
+
+
+
+
+
+
+netmiko.juniper API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.juniper
+
+
+
+Source code
+from netmiko.juniper.juniper import JuniperSSH, JuniperTelnet, JuniperFileTransfer
+from netmiko.juniper.juniper_screenos import JuniperScreenOsSSH
+
+__all__ = ["JuniperSSH", "JuniperTelnet", "JuniperFileTransfer", "JuniperScreenOsSSH"]
+
+
+
+
+
+
+
+
+
+class JuniperFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/var/tmp', direction='put', **kwargs)
+
+-
+
Juniper SCP File Transfer driver.
+
+Source code
+class JuniperFileTransfer(BaseFileTransfer):
+ """Juniper SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "file checksum md5", remote_file: Optional[str] = None
+ ) -> str:
+ return super().remote_md5(base_cmd=base_cmd, remote_file=remote_file)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+-
+
Implement methods for interacting with Juniper Networks devices.
+methods.
+Overrides several methods for Juniper-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperSSH(JuniperBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class JuniperScreenOsSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with Juniper ScreenOS devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperScreenOsSSH(NoEnable, NoConfig, BaseConnection):
+ """
+ Implement methods for interacting with Juniper ScreenOS devices.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
+
+
+
+def session_preparation(self)
+
+-
+
ScreenOS can be configured to require: Accept this agreement y/[n]
+
+Source code
+def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+
+
+Inherited members
+
+
+
+class JuniperTelnet
+(*args, **kwargs)
+
+-
+
Implement methods for interacting with Juniper Networks devices.
+methods.
+Overrides several methods for Juniper-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperTelnet(JuniperBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/juniper/juniper.html b/docs/netmiko/juniper/juniper.html
new file mode 100644
index 000000000..16a6cb49c
--- /dev/null
+++ b/docs/netmiko/juniper/juniper.html
@@ -0,0 +1,1468 @@
+
+
+
+
+
+
+netmiko.juniper.juniper API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.juniper.juniper
+
+
+
+Source code
+import re
+import time
+import warnings
+from typing import Optional, Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.scp_handler import BaseFileTransfer
+
+
+class JuniperBase(NoEnable, BaseConnection):
+ """
+ Implement methods for interacting with Juniper Networks devices.
+
+ methods. Overrides several methods for Juniper-specific compatibility.
+ """
+
+ def session_preparation(self) -> None:
+ """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()
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
+
+ def _return_cli(self) -> str:
+ """Return to the Juniper CLI."""
+ return self._send_command_str("exit", expect_string=r"[#>]")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"root@", cur_prompt) or re.search(r"^%$", cur_prompt.strip()):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "#" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure",
+ pattern: str = r"Entering configuration mode",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "commit complete"
+ if check:
+ command_string = "commit check"
+ commit_marker = "configuration check succeeds"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ # and_quit will get out of config mode on commit
+
+ expect_string = re.escape(self.base_prompt) if and_quit else None
+
+ output += self._send_command_str(
+ command_string,
+ expect_string=expect_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self.strip_context_items(a_string)
+
+ def strip_context_items(self, a_string: str) -> str:
+ """Strip Juniper-specific output.
+
+ Juniper will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"\[edit.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+
+class JuniperSSH(JuniperBase):
+ pass
+
+
+class JuniperTelnet(JuniperBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class JuniperFileTransfer(BaseFileTransfer):
+ """Juniper SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "file checksum md5", remote_file: Optional[str] = None
+ ) -> str:
+ return super().remote_md5(base_cmd=base_cmd, remote_file=remote_file)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class JuniperBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with Juniper Networks devices.
+methods.
+Overrides several methods for Juniper-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperBase(NoEnable, BaseConnection):
+ """
+ Implement methods for interacting with Juniper Networks devices.
+
+ methods. Overrides several methods for Juniper-specific compatibility.
+ """
+
+ def session_preparation(self) -> None:
+ """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()
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
+
+ def _return_cli(self) -> str:
+ """Return to the Juniper CLI."""
+ return self._send_command_str("exit", expect_string=r"[#>]")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"root@", cur_prompt) or re.search(r"^%$", cur_prompt.strip()):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "#" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure",
+ pattern: str = r"Entering configuration mode",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "commit complete"
+ if check:
+ command_string = "commit check"
+ commit_marker = "configuration check succeeds"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ # and_quit will get out of config mode on commit
+
+ expect_string = re.escape(self.base_prompt) if and_quit else None
+
+ output += self._send_command_str(
+ command_string,
+ expect_string=expect_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self.strip_context_items(a_string)
+
+ def strip_context_items(self, a_string: str) -> str:
+ """Strip Juniper-specific output.
+
+ Juniper will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"\[edit.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+Ancestors
+
+Subclasses
+
+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: str = "]", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string)
+
+
+
+def cleanup(self, command='exit')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+
+
+def commit(self, confirm=False, confirm_delay=None, check=False, comment='', and_quit=False, read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration. Raise an error and return the failure
+if the commit fails.
+Automatically enters configuration mode
+default:
+command_string = commit
+check and (confirm or confirm_dely or comment):
+Exception
+confirm_delay and no confirm:
+Exception
+confirm:
+confirm_delay option
+comment option
+command_string = commit confirmed or commit confirmed
+check:
+command_string = commit check
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed <confirm_delay>
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "commit complete"
+ if check:
+ command_string = "commit check"
+ commit_marker = "configuration check succeeds"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ # and_quit will get out of config mode on commit
+
+ expect_string = re.escape(self.base_prompt) if and_quit else None
+
+ output += self._send_command_str(
+ command_string,
+ expect_string=expect_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+
+
+def config_mode(self, config_command='configure', pattern='Entering configuration mode', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"Entering configuration mode",
+ re_flags: int = 0,
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def enter_cli_mode(self)
+
+-
+
Check if at shell prompt root@ and go into CLI.
+
+Source code
+def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"root@", cur_prompt) or re.search(r"^%$", cur_prompt.strip()):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "#" in cur_prompt:
+ break
+ count += 1
+
+
+
+def exit_config_mode(self, exit_config='exit configuration-mode', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "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.
+
+Source code
+def session_preparation(self) -> None:
+ """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()
+
+
+
+def strip_context_items(self, a_string)
+
+-
+
Strip Juniper-specific output.
+Juniper will also put a configuration context:
+[edit]
+and various chassis contexts:
+{master:0}, {backup:1}
+This method removes those lines.
+
+Source code
+def strip_context_items(self, a_string: str) -> str:
+ """Strip Juniper-specific output.
+
+ Juniper will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"\[edit.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
+
+
+
+def strip_prompt(self, *args, **kwargs)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self.strip_context_items(a_string)
+
+
+
+Inherited members
+
+
+
+class JuniperFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/var/tmp', direction='put', **kwargs)
+
+-
+
Juniper SCP File Transfer driver.
+
+Source code
+class JuniperFileTransfer(BaseFileTransfer):
+ """Juniper SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "file checksum md5", remote_file: Optional[str] = None
+ ) -> str:
+ return super().remote_md5(base_cmd=base_cmd, remote_file=remote_file)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+-
+
Implement methods for interacting with Juniper Networks devices.
+methods.
+Overrides several methods for Juniper-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperSSH(JuniperBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class JuniperTelnet
+(*args, **kwargs)
+
+-
+
Implement methods for interacting with Juniper Networks devices.
+methods.
+Overrides several methods for Juniper-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperTelnet(JuniperBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/juniper/juniper_screenos.html b/docs/netmiko/juniper/juniper_screenos.html
new file mode 100644
index 000000000..d5f174581
--- /dev/null
+++ b/docs/netmiko/juniper/juniper_screenos.html
@@ -0,0 +1,336 @@
+
+
+
+
+
+
+netmiko.juniper.juniper_screenos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.juniper.juniper_screenos
+
+
+
+Source code
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class JuniperScreenOsSSH(NoEnable, NoConfig, BaseConnection):
+ """
+ Implement methods for interacting with Juniper ScreenOS devices.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
+
+
+
+
+
+
+
+
+
+class JuniperScreenOsSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with Juniper ScreenOS devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class JuniperScreenOsSSH(NoEnable, NoConfig, BaseConnection):
+ """
+ Implement methods for interacting with Juniper ScreenOS devices.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='save config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
+
+
+
+def session_preparation(self)
+
+-
+
ScreenOS can be configured to require: Accept this agreement y/[n]
+
+Source code
+def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/keymile/index.html b/docs/netmiko/keymile/index.html
new file mode 100644
index 000000000..528bda949
--- /dev/null
+++ b/docs/netmiko/keymile/index.html
@@ -0,0 +1,463 @@
+
+
+
+
+
+
+netmiko.keymile API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.keymile
+
+
+
+Source code
+from netmiko.keymile.keymile_ssh import KeymileSSH
+from netmiko.keymile.keymile_nos_ssh import KeymileNOSSSH
+
+__all__ = ["KeymileSSH", "KeymileNOSSSH"]
+
+
+
+
+
+
+
+
+
+class KeymileNOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Common Methods for IOS (both SSH and telnet).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class KeymileNOSSSH(CiscoIosBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ self.disable_paging()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ output = super()._test_channel_read(count=count, pattern=pattern)
+ pattern = r"Login incorrect"
+ if re.search(pattern, output):
+ self.paramiko_cleanup()
+ msg = "Authentication failure: unable to connect"
+ msg += f"{self.device_type} {self.host}:{self.port}"
+ msg += self.RESPONSE_RETURN + "Login incorrect"
+ raise NetmikoAuthenticationException(msg)
+ else:
+ return output
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Since Keymile NOS always returns True on paramiko.connect() we
+check the output for substring Login incorrect after connecting.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
+
+
+
+Inherited members
+
+
+
+class KeymileSSH
+(**kwargs)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+
+Source code
+class KeymileSSH(NoEnable, NoConfig, CiscoIosBase):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("default_enter", "\r\n")
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Keymile does not use paging.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='>', delay_factor=1.0, pattern=None)
+
+-
+
set prompt termination to >
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Remove appending empty line and prompt from output
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/keymile/keymile_nos_ssh.html b/docs/netmiko/keymile/keymile_nos_ssh.html
new file mode 100644
index 000000000..766fb2325
--- /dev/null
+++ b/docs/netmiko/keymile/keymile_nos_ssh.html
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+netmiko.keymile.keymile_nos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.keymile.keymile_nos_ssh
+
+
+
+Source code
+import time
+import re
+
+
+from netmiko.cisco.cisco_ios import CiscoIosBase
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class KeymileNOSSSH(CiscoIosBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ self.disable_paging()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ output = super()._test_channel_read(count=count, pattern=pattern)
+ pattern = r"Login incorrect"
+ if re.search(pattern, output):
+ self.paramiko_cleanup()
+ msg = "Authentication failure: unable to connect"
+ msg += f"{self.device_type} {self.host}:{self.port}"
+ msg += self.RESPONSE_RETURN + "Login incorrect"
+ raise NetmikoAuthenticationException(msg)
+ else:
+ return output
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
+
+
+
+
+
+
+
+
+
+class KeymileNOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Common Methods for IOS (both SSH and telnet).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class KeymileNOSSSH(CiscoIosBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ self.disable_paging()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ output = super()._test_channel_read(count=count, pattern=pattern)
+ pattern = r"Login incorrect"
+ if re.search(pattern, output):
+ self.paramiko_cleanup()
+ msg = "Authentication failure: unable to connect"
+ msg += f"{self.device_type} {self.host}:{self.port}"
+ msg += self.RESPONSE_RETURN + "Login incorrect"
+ raise NetmikoAuthenticationException(msg)
+ else:
+ return output
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Since Keymile NOS always returns True on paramiko.connect() we
+check the output for substring Login incorrect after connecting.
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/keymile/keymile_ssh.html b/docs/netmiko/keymile/keymile_ssh.html
new file mode 100644
index 000000000..e95cc85ed
--- /dev/null
+++ b/docs/netmiko/keymile/keymile_ssh.html
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+netmiko.keymile.keymile_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.keymile.keymile_ssh
+
+
+
+Source code
+from typing import Any, Optional
+import time
+
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco.cisco_ios import CiscoIosBase
+
+
+class KeymileSSH(NoEnable, NoConfig, CiscoIosBase):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("default_enter", "\r\n")
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+
+
+
+
+
+
+class KeymileSSH
+(**kwargs)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+
+Source code
+class KeymileSSH(NoEnable, NoConfig, CiscoIosBase):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("default_enter", "\r\n")
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Keymile does not use paging.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='>', delay_factor=1.0, pattern=None)
+
+-
+
set prompt termination to >
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Remove appending empty line and prompt from output
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/linux/index.html b/docs/netmiko/linux/index.html
new file mode 100644
index 000000000..4a2afa66d
--- /dev/null
+++ b/docs/netmiko/linux/index.html
@@ -0,0 +1,683 @@
+
+
+
+
+
+
+netmiko.linux API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.linux.linux_ssh import LinuxSSH, LinuxFileTransfer
+
+__all__ = ["LinuxSSH", "LinuxFileTransfer"]
+
+
+
+
+
+
+
+
+
+class LinuxFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/var/tmp', direction='put', **kwargs)
+
+-
+
Linux SCP File Transfer driver.
+Mostly for testing purposes.
+
+Source code
+class LinuxFileTransfer(CiscoFileTransfer):
+ """
+ Linux SCP File Transfer driver.
+
+ Mostly for testing purposes.
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "md5sum", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5).strip()
+ return dest_md5
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^(\S+)\s+") -> str:
+ return super(LinuxFileTransfer, LinuxFileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+class LinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class LinuxSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ return super().session_preparation()
+
+ def _enter_shell(self) -> str:
+ """Already in shell."""
+ return ""
+
+ def _return_cli(self) -> str:
+ """The shell is the CLI."""
+ return ""
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Linux doesn't have paging by default."""
+ return ""
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """Can't exit from root (if root)"""
+ if self.username == "root":
+ exit_config_mode = False
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+ ) -> bool:
+ """Verify root"""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ return self.exit_enable_mode(exit_command=exit_config)
+
+ def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
+ """Verify root"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(0.3 * delay_factor)
+ self.set_base_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(0.3 * delay_factor)
+ try:
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ self.set_base_prompt()
+ except socket.timeout:
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Try to Gracefully exit the SSH session."""
+ return super().cleanup(command=command)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
+
+Source code
+def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+) -> bool:
+ """Verify root"""
+ return self.check_enable_mode(check_string=check_string)
+
+
+
+def check_enable_mode(self, check_string='#')
+
+-
+
+
+Source code
+def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
+ """Verify root"""
+ return super().check_enable_mode(check_string=check_string)
+
+
+
+def cleanup(self, command='exit')
+
+-
+
Try to Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """Try to Gracefully exit the SSH session."""
+ return super().cleanup(command=command)
+
+
+
+def config_mode(self, config_command='sudo -s', pattern='ssword', re_flags=)
+
+-
+
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Attempt to become root."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Linux doesn't have paging by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Linux doesn't have paging by default."""
+ return ""
+
+
+
+def enable(self, cmd='sudo -s', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Attempt to become root."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(0.3 * delay_factor)
+ try:
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ self.set_base_prompt()
+ except socket.timeout:
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(0.3 * delay_factor)
+ self.set_base_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=True, **kwargs)
+
+-
+
Can't exit from root (if root)
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+) -> str:
+ """Can't exit from root (if root)"""
+ if self.username == "root":
+ exit_config_mode = False
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ return super().session_preparation()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/linux/linux_ssh.html b/docs/netmiko/linux/linux_ssh.html
new file mode 100644
index 000000000..6f2fdc570
--- /dev/null
+++ b/docs/netmiko/linux/linux_ssh.html
@@ -0,0 +1,873 @@
+
+
+
+
+
+
+netmiko.linux.linux_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.linux.linux_ssh
+
+
+
+Source code
+from typing import Any, Optional, TYPE_CHECKING, Union, Sequence, TextIO
+import os
+import re
+import socket
+import time
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.cisco_base_connection import CiscoFileTransfer
+from netmiko.exceptions import NetmikoTimeoutException
+
+LINUX_PROMPT_PRI = os.getenv("NETMIKO_LINUX_PROMPT_PRI", "$")
+LINUX_PROMPT_ALT = os.getenv("NETMIKO_LINUX_PROMPT_ALT", "#")
+LINUX_PROMPT_ROOT = os.getenv("NETMIKO_LINUX_PROMPT_ROOT", "#")
+
+
+class LinuxSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ return super().session_preparation()
+
+ def _enter_shell(self) -> str:
+ """Already in shell."""
+ return ""
+
+ def _return_cli(self) -> str:
+ """The shell is the CLI."""
+ return ""
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Linux doesn't have paging by default."""
+ return ""
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """Can't exit from root (if root)"""
+ if self.username == "root":
+ exit_config_mode = False
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+ ) -> bool:
+ """Verify root"""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ return self.exit_enable_mode(exit_command=exit_config)
+
+ def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
+ """Verify root"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(0.3 * delay_factor)
+ self.set_base_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(0.3 * delay_factor)
+ try:
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ self.set_base_prompt()
+ except socket.timeout:
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Try to Gracefully exit the SSH session."""
+ return super().cleanup(command=command)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+class LinuxFileTransfer(CiscoFileTransfer):
+ """
+ Linux SCP File Transfer driver.
+
+ Mostly for testing purposes.
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "md5sum", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5).strip()
+ return dest_md5
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^(\S+)\s+") -> str:
+ return super(LinuxFileTransfer, LinuxFileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class LinuxFileTransfer
+(ssh_conn, source_file, dest_file, file_system='/var/tmp', direction='put', **kwargs)
+
+-
+
Linux SCP File Transfer driver.
+Mostly for testing purposes.
+
+Source code
+class LinuxFileTransfer(CiscoFileTransfer):
+ """
+ Linux SCP File Transfer driver.
+
+ Mostly for testing purposes.
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """Return space available on remote device."""
+ return self._remote_space_available_unix(search_pattern=search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ return self._check_file_exists_unix(remote_cmd=remote_cmd)
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """Get the file size of the remote file."""
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "md5sum", remote_file: Optional[str] = None
+ ) -> str:
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5).strip()
+ return dest_md5
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^(\S+)\s+") -> str:
+ return super(LinuxFileTransfer, LinuxFileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def enable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+ def disable_scp(self, cmd: str = "") -> None:
+ raise NotImplementedError
+
+Ancestors
+
+Inherited members
+
+
+
+class LinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class LinuxSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ return super().session_preparation()
+
+ def _enter_shell(self) -> str:
+ """Already in shell."""
+ return ""
+
+ def _return_cli(self) -> str:
+ """The shell is the CLI."""
+ return ""
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Linux doesn't have paging by default."""
+ return ""
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """Can't exit from root (if root)"""
+ if self.username == "root":
+ exit_config_mode = False
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+ ) -> bool:
+ """Verify root"""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ return self.exit_enable_mode(exit_command=exit_config)
+
+ def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
+ """Verify root"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(0.3 * delay_factor)
+ self.set_base_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Attempt to become root."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(0.3 * delay_factor)
+ try:
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ self.set_base_prompt()
+ except socket.timeout:
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Try to Gracefully exit the SSH session."""
+ return super().cleanup(command=command)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
+
+Source code
+def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+) -> bool:
+ """Verify root"""
+ return self.check_enable_mode(check_string=check_string)
+
+
+
+def check_enable_mode(self, check_string='#')
+
+-
+
+
+Source code
+def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
+ """Verify root"""
+ return super().check_enable_mode(check_string=check_string)
+
+
+
+def cleanup(self, command='exit')
+
+-
+
Try to Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """Try to Gracefully exit the SSH session."""
+ return super().cleanup(command=command)
+
+
+
+def config_mode(self, config_command='sudo -s', pattern='ssword', re_flags=)
+
+-
+
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Attempt to become root."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Linux doesn't have paging by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Linux doesn't have paging by default."""
+ return ""
+
+
+
+def enable(self, cmd='sudo -s', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Attempt to become root."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(0.3 * delay_factor)
+ try:
+ output += self.read_channel()
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ self.set_base_prompt()
+ except socket.timeout:
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(0.3 * delay_factor)
+ self.set_base_prompt()
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=True, **kwargs)
+
+-
+
Can't exit from root (if root)
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+) -> str:
+ """Can't exit from root (if root)"""
+ if self.username == "root":
+ exit_config_mode = False
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ return super().session_preparation()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mellanox/index.html b/docs/netmiko/mellanox/index.html
new file mode 100644
index 000000000..1576f6efe
--- /dev/null
+++ b/docs/netmiko/mellanox/index.html
@@ -0,0 +1,415 @@
+
+
+
+
+
+
+netmiko.mellanox API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mellanox
+
+
+
+Source code
+from netmiko.mellanox.mellanox_mlnxos_ssh import MellanoxMlnxosSSH
+
+__all__ = ["MellanoxMlnxosSSH"]
+
+
+
+
+
+
+
+
+
+class MellanoxMlnxosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Mellanox MLNX-OS Switch support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MellanoxMlnxosSSH(CiscoSSHConnection):
+ """Mellanox MLNX-OS Switch support."""
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config term",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def disable_paging(
+ self,
+ command: str = "no cli session paging enable",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
+
+Ancestors
+
+Methods
+
+
+def enable(self, cmd='enable', pattern='#', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='#')
+
+-
+
Mellanox does not support a single command to completely exit configuration mode.
+Consequently, need to keep checking and sending "exit".
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+
+
+def save_config(self, cmd='configuration write', confirm=False, confirm_response='')
+
+-
+
Save Config on Mellanox devices Enters and Leaves Config Mode
+
+Source code
+def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html
new file mode 100644
index 000000000..5add9c30e
--- /dev/null
+++ b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html
@@ -0,0 +1,493 @@
+
+
+
+
+
+
+netmiko.mellanox.mellanox_mlnxos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mellanox.mellanox_mlnxos_ssh
+
+
+Mellanox MLNX-OS Switch support.
+
+Source code
+"""Mellanox MLNX-OS Switch support."""
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+
+
+class MellanoxMlnxosSSH(CiscoSSHConnection):
+ """Mellanox MLNX-OS Switch support."""
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config term",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def disable_paging(
+ self,
+ command: str = "no cli session paging enable",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
+
+
+
+
+
+
+
+
+
+class MellanoxMlnxosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Mellanox MLNX-OS Switch support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MellanoxMlnxosSSH(CiscoSSHConnection):
+ """Mellanox MLNX-OS Switch support."""
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config term",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def disable_paging(
+ self,
+ command: str = "no cli session paging enable",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
+
+Ancestors
+
+Methods
+
+
+def enable(self, cmd='enable', pattern='#', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='#')
+
+-
+
Mellanox does not support a single command to completely exit configuration mode.
+Consequently, need to keep checking and sending "exit".
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+
+
+def save_config(self, cmd='configuration write', confirm=False, confirm_response='')
+
+-
+
Save Config on Mellanox devices Enters and Leaves Config Mode
+
+Source code
+def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mellanox/mellanox_ssh.html b/docs/netmiko/mellanox/mellanox_ssh.html
new file mode 100644
index 000000000..2629f6041
--- /dev/null
+++ b/docs/netmiko/mellanox/mellanox_ssh.html
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+netmiko.mellanox.mellanox_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mellanox.mellanox_ssh
+
+
+
+Source code
+from __future__ import unicode_literals
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+import time
+
+
+class MellanoxSSH(CiscoSSHConnection):
+ def config_mode(self, config_command="config term", pattern="#"):
+ """Enter into config_mode."""
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ output = self.read_until_pattern(pattern=pattern)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+ def check_config_mode(self, check_string="(config)", pattern=r"[>|#]"):
+ return super(MellanoxSSH, self).check_config_mode(
+ check_string=check_string, pattern=pattern
+ )
+
+ def disable_paging(self, command="terminal length 999", delay_factor=1):
+ """Disable paging default to a Cisco CLI method."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug("Command: {0}".format(command))
+ self.write_channel(command)
+ output = self.read_until_prompt()
+ if self.ansi_escape_codes:
+ output = self.strip_ansi_escape_codes(output)
+ log.debug("{0}".format(output))
+ log.debug("Exiting disable_paging")
+ return output
+
+ def exit_config_mode(self, exit_config="exit", pattern="#"):
+ """Exit from configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output = self.read_until_pattern(pattern=pattern)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug("exit_config_mode: {0}".format(output))
+ return output
+
+ def save_config(
+ self, cmd="configuration write", confirm=False, confirm_response=""
+ ):
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self.send_command(cmd)
+ output += self.exit_config_mode()
+ return output
+
+
+
+
+
+
+
+
+
+class MellanoxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, 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, timeout=100, session_timeout=60, auth_timeout=None, blocking_timeout=8, banner_timeout=5, 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')
+
+-
+
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 user's '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
+
+
+Source code
+class MellanoxSSH(CiscoSSHConnection):
+ def config_mode(self, config_command="config term", pattern="#"):
+ """Enter into config_mode."""
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ output = self.read_until_pattern(pattern=pattern)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+ def check_config_mode(self, check_string="(config)", pattern=r"[>|#]"):
+ return super(MellanoxSSH, self).check_config_mode(
+ check_string=check_string, pattern=pattern
+ )
+
+ def disable_paging(self, command="terminal length 999", delay_factor=1):
+ """Disable paging default to a Cisco CLI method."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug("Command: {0}".format(command))
+ self.write_channel(command)
+ output = self.read_until_prompt()
+ if self.ansi_escape_codes:
+ output = self.strip_ansi_escape_codes(output)
+ log.debug("{0}".format(output))
+ log.debug("Exiting disable_paging")
+ return output
+
+ def exit_config_mode(self, exit_config="exit", pattern="#"):
+ """Exit from configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output = self.read_until_pattern(pattern=pattern)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug("exit_config_mode: {0}".format(output))
+ return output
+
+ def save_config(
+ self, cmd="configuration write", confirm=False, confirm_response=""
+ ):
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self.send_command(cmd)
+ output += self.exit_config_mode()
+ return output
+
+Ancestors
+
+Methods
+
+
+def config_mode(self, config_command='config term', pattern='#')
+
+-
+
+
+Source code
+def config_mode(self, config_command="config term", pattern="#"):
+ """Enter into config_mode."""
+ output = ""
+ if not self.check_config_mode():
+ self.write_channel(self.normalize_cmd(config_command))
+ output = self.read_until_pattern(pattern=pattern)
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode.")
+ return output
+
+
+
+def disable_paging(self, command='terminal length 999', delay_factor=1)
+
+-
+
Disable paging default to a Cisco CLI method.
+
+Source code
+def disable_paging(self, command="terminal length 999", delay_factor=1):
+ """Disable paging default to a Cisco CLI method."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_paging")
+ log.debug("Command: {0}".format(command))
+ self.write_channel(command)
+ output = self.read_until_prompt()
+ if self.ansi_escape_codes:
+ output = self.strip_ansi_escape_codes(output)
+ log.debug("{0}".format(output))
+ log.debug("Exiting disable_paging")
+ return output
+
+
+
+def save_config(self, cmd='configuration write', confirm=False, confirm_response='')
+
+-
+
Save Config on Mellanox devices Enters and Leaves Config Mode
+
+Source code
+def save_config(
+ self, cmd="configuration write", confirm=False, confirm_response=""
+):
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self.send_command(cmd)
+ output += self.exit_config_mode()
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mikrotik/index.html b/docs/netmiko/mikrotik/index.html
new file mode 100644
index 000000000..6a52e5401
--- /dev/null
+++ b/docs/netmiko/mikrotik/index.html
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+netmiko.mikrotik API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mikrotik
+
+
+
+Source code
+from netmiko.mikrotik.mikrotik_ssh import MikrotikRouterOsSSH
+from netmiko.mikrotik.mikrotik_ssh import MikrotikSwitchOsSSH
+
+__all__ = ["MikrotikRouterOsSSH", "MikrotikSwitchOsSSH"]
+
+
+
+
+
+
+
+
+
+class MikrotikRouterOsSSH
+(**kwargs)
+
+-
+
Mikrotik RouterOS SSH driver.
+
+Source code
+class MikrotikRouterOsSSH(MikrotikBase):
+ """Mikrotik RouterOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class MikrotikSwitchOsSSH
+(**kwargs)
+
+-
+
Mikrotik SwitchOS SSH driver.
+
+Source code
+class MikrotikSwitchOsSSH(MikrotikBase):
+ """Mikrotik SwitchOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mikrotik/mikrotik_ssh.html b/docs/netmiko/mikrotik/mikrotik_ssh.html
new file mode 100644
index 000000000..8349fb62e
--- /dev/null
+++ b/docs/netmiko/mikrotik/mikrotik_ssh.html
@@ -0,0 +1,666 @@
+
+
+
+
+
+
+netmiko.mikrotik.mikrotik_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mikrotik.mikrotik_ssh
+
+
+
+Source code
+from typing import Any, Union, List, Dict, Optional
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class MikrotikBase(NoEnable, CiscoSSHConnection):
+ """Common Methods for Mikrotik RouterOS and SwitchOS"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+
+ self._in_config_mode = False
+
+ return super().__init__(**kwargs)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"\].*>")
+ self.set_base_prompt()
+
+ def _modify_connection_params(self) -> None:
+ """Append login options to username
+ c: disable console colors
+ e: enable dumb terminal mode
+ t: disable auto detect terminal capabilities
+ w511: set term width
+ h4098: set term height
+ """
+ self.username += "+ctw511h4098"
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Mikrotik does not have paging by default."""
+ return ""
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save command, all configuration is atomic"""
+ return ""
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = True
+ return ""
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return self._in_config_mode
+
+ def exit_config_mode(self, exit_config: str = ">", pattern: str = "") -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = False
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ Mikrotik just does a lot of formatting/has ansi escape codes in output so
+ we need a special handler here.
+
+ There can be two trailing instances of the prompt probably due to
+ repainting.
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ # Drop the first trailing prompt
+ if self.base_prompt in last_line:
+ a_string = self.RESPONSE_RETURN.join(response_list[:-1])
+ a_string = a_string.rstrip()
+ # Now it should be just normal: call the parent method
+ a_string = super().strip_prompt(a_string)
+ return a_string.strip()
+ else:
+ # Unexpected just return the original string
+ return a_string
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Strip the trailing space off."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def send_command_timing( # type: ignore
+ self,
+ command_string: str,
+ cmd_verify: bool = True,
+ **kwargs: Any,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Force cmd_verify to be True due to all of the line repainting"""
+ return super()._send_command_timing_str(
+ command_string=command_string, cmd_verify=cmd_verify, **kwargs
+ )
+
+
+class MikrotikRouterOsSSH(MikrotikBase):
+ """Mikrotik RouterOS SSH driver."""
+
+ pass
+
+
+class MikrotikSwitchOsSSH(MikrotikBase):
+ """Mikrotik SwitchOS SSH driver."""
+
+ pass
+
+
+
+
+
+
+
+
+
+class MikrotikBase
+(**kwargs)
+
+-
+
Common Methods for Mikrotik RouterOS and SwitchOS
+
+Source code
+class MikrotikBase(NoEnable, CiscoSSHConnection):
+ """Common Methods for Mikrotik RouterOS and SwitchOS"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+
+ self._in_config_mode = False
+
+ return super().__init__(**kwargs)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"\].*>")
+ self.set_base_prompt()
+
+ def _modify_connection_params(self) -> None:
+ """Append login options to username
+ c: disable console colors
+ e: enable dumb terminal mode
+ t: disable auto detect terminal capabilities
+ w511: set term width
+ h4098: set term height
+ """
+ self.username += "+ctw511h4098"
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Mikrotik does not have paging by default."""
+ return ""
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save command, all configuration is atomic"""
+ return ""
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = True
+ return ""
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return self._in_config_mode
+
+ def exit_config_mode(self, exit_config: str = ">", pattern: str = "") -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = False
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ Mikrotik just does a lot of formatting/has ansi escape codes in output so
+ we need a special handler here.
+
+ There can be two trailing instances of the prompt probably due to
+ repainting.
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ # Drop the first trailing prompt
+ if self.base_prompt in last_line:
+ a_string = self.RESPONSE_RETURN.join(response_list[:-1])
+ a_string = a_string.rstrip()
+ # Now it should be just normal: call the parent method
+ a_string = super().strip_prompt(a_string)
+ return a_string.strip()
+ else:
+ # Unexpected just return the original string
+ return a_string
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Strip the trailing space off."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def send_command_timing( # type: ignore
+ self,
+ command_string: str,
+ cmd_verify: bool = True,
+ **kwargs: Any,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Force cmd_verify to be True due to all of the line repainting"""
+ return super()._send_command_timing_str(
+ command_string=command_string, cmd_verify=cmd_verify, **kwargs
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
Checks whether in configuration mode. Returns a boolean.
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return self._in_config_mode
+
+
+
+def config_mode(self, config_command='', pattern='', re_flags=0)
+
+-
+
No configuration mode on Mikrotik
+
+Source code
+def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+) -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = True
+ return ""
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
Mikrotik does not have paging by default.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Mikrotik does not have paging by default."""
+ return ""
+
+
+
+def exit_config_mode(self, exit_config='>', pattern='')
+
+-
+
No configuration mode on Mikrotik
+
+Source code
+def exit_config_mode(self, exit_config: str = ">", pattern: str = "") -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = False
+ return ""
+
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
No save command, all configuration is atomic
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save command, all configuration is atomic"""
+ return ""
+
+
+
+def send_command_timing(self, command_string, cmd_verify=True, **kwargs)
+
+-
+
Force cmd_verify to be True due to all of the line repainting
+
+Source code
+def send_command_timing( # type: ignore
+ self,
+ command_string: str,
+ cmd_verify: bool = True,
+ **kwargs: Any,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """Force cmd_verify to be True due to all of the line repainting"""
+ return super()._send_command_timing_str(
+ command_string=command_string, cmd_verify=cmd_verify, **kwargs
+ )
+
+
+
+def session_preparation(self, *args, **kwargs)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"\].*>")
+ self.set_base_prompt()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='>', delay_factor=1.0, pattern=None)
+
+-
+
Strip the trailing space off.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Strip the trailing space off."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+Mikrotik just does a lot of formatting/has ansi escape codes in output so
+we need a special handler here.
+There can be two trailing instances of the prompt probably due to
+repainting.
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ Mikrotik just does a lot of formatting/has ansi escape codes in output so
+ we need a special handler here.
+
+ There can be two trailing instances of the prompt probably due to
+ repainting.
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ # Drop the first trailing prompt
+ if self.base_prompt in last_line:
+ a_string = self.RESPONSE_RETURN.join(response_list[:-1])
+ a_string = a_string.rstrip()
+ # Now it should be just normal: call the parent method
+ a_string = super().strip_prompt(a_string)
+ return a_string.strip()
+ else:
+ # Unexpected just return the original string
+ return a_string
+
+
+
+Inherited members
+
+
+
+class MikrotikRouterOsSSH
+(**kwargs)
+
+-
+
Mikrotik RouterOS SSH driver.
+
+Source code
+class MikrotikRouterOsSSH(MikrotikBase):
+ """Mikrotik RouterOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class MikrotikSwitchOsSSH
+(**kwargs)
+
+-
+
Mikrotik SwitchOS SSH driver.
+
+Source code
+class MikrotikSwitchOsSSH(MikrotikBase):
+ """Mikrotik SwitchOS SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mrv/index.html b/docs/netmiko/mrv/index.html
new file mode 100644
index 000000000..2d7a8c246
--- /dev/null
+++ b/docs/netmiko/mrv/index.html
@@ -0,0 +1,634 @@
+
+
+
+
+
+
+netmiko.mrv API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.mrv.mrv_lx import MrvLxSSH
+from netmiko.mrv.mrv_ssh import MrvOptiswitchSSH
+
+__all__ = ["MrvOptiswitchSSH", "MrvLxSSH"]
+
+
+
+
+
+
+
+
+
+class MrvLxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
MRV Communications Driver (LX).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MrvLxSSH(CiscoSSHConnection):
+ """MRV Communications Driver (LX)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "assword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def check_enable_mode(self, check_string='>>')
+
+-
+
MRV has a >> for enable mode instead of # like Cisco
+
+Source code
+def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+
+
+def save_config(self, cmd='save config flash', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class MrvOptiswitchSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
MRV Communications Driver (OptiSwitch).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MrvOptiswitchSSH(CiscoSSHConnection):
+ """MRV Communications Driver (OptiSwitch)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no cli-paging")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enable mode on MRV uses no password."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def enable(self, cmd='enable', pattern='#', enable_pattern=None, re_flags=)
+
+-
+
Enable mode on MRV uses no password.
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enable mode on MRV uses no password."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+
+
+def save_config(self, cmd='save config flash', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no cli-paging")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mrv/mrv_lx.html b/docs/netmiko/mrv/mrv_lx.html
new file mode 100644
index 000000000..376040575
--- /dev/null
+++ b/docs/netmiko/mrv/mrv_lx.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+netmiko.mrv.mrv_lx API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mrv.mrv_lx
+
+
+MRV Communications Driver (LX).
+
+Source code
+"""MRV Communications Driver (LX)."""
+import time
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class MrvLxSSH(CiscoSSHConnection):
+ """MRV Communications Driver (LX)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "assword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class MrvLxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
MRV Communications Driver (LX).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MrvLxSSH(CiscoSSHConnection):
+ """MRV Communications Driver (LX)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "assword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def check_enable_mode(self, check_string='>>')
+
+-
+
MRV has a >> for enable mode instead of # like Cisco
+
+Source code
+def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+
+
+def save_config(self, cmd='save config flash', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/mrv/mrv_ssh.html b/docs/netmiko/mrv/mrv_ssh.html
new file mode 100644
index 000000000..ad9682e6d
--- /dev/null
+++ b/docs/netmiko/mrv/mrv_ssh.html
@@ -0,0 +1,407 @@
+
+
+
+
+
+
+netmiko.mrv.mrv_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.mrv.mrv_ssh
+
+
+MRV Communications Driver (OptiSwitch).
+
+Source code
+"""MRV Communications Driver (OptiSwitch)."""
+import time
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class MrvOptiswitchSSH(CiscoSSHConnection):
+ """MRV Communications Driver (OptiSwitch)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no cli-paging")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enable mode on MRV uses no password."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class MrvOptiswitchSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
MRV Communications Driver (OptiSwitch).
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class MrvOptiswitchSSH(CiscoSSHConnection):
+ """MRV Communications Driver (OptiSwitch)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no cli-paging")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enable mode on MRV uses no password."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def enable(self, cmd='enable', pattern='#', enable_pattern=None, re_flags=)
+
+-
+
Enable mode on MRV uses no password.
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enable mode on MRV uses no password."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+ return output
+
+
+
+def save_config(self, cmd='save config flash', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no cli-paging")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/netapp/index.html b/docs/netmiko/netapp/index.html
new file mode 100644
index 000000000..c447ef15f
--- /dev/null
+++ b/docs/netmiko/netapp/index.html
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+netmiko.netapp API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.netapp.netapp_cdot_ssh import NetAppcDotSSH
+
+__all__ = ["NetAppcDotSSH"]
+
+
+
+
+
+
+
+
+
+class NetAppcDotSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetAppcDotSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ cmd = self.RETURN + "rows 0" + self.RETURN
+ self.disable_paging(command=cmd)
+
+ def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def check_config_mode(self, check_string: str = "*>", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "set -privilege diagnostic -confirmations off",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self,
+ exit_config: str = "set -privilege admin -confirmations off",
+ pattern: str = "",
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+Ancestors
+
+Methods
+
+
+def send_command_with_y(self, *args, **kwargs)
+
+-
+
+
+Source code
+def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ cmd = self.RETURN + "rows 0" + self.RETURN
+ self.disable_paging(command=cmd)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/netapp/netapp_cdot_ssh.html b/docs/netmiko/netapp/netapp_cdot_ssh.html
new file mode 100644
index 000000000..52a907e5c
--- /dev/null
+++ b/docs/netmiko/netapp/netapp_cdot_ssh.html
@@ -0,0 +1,349 @@
+
+
+
+
+
+
+netmiko.netapp.netapp_cdot_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.netapp.netapp_cdot_ssh
+
+
+
+Source code
+from typing import Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection
+
+
+class NetAppcDotSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ cmd = self.RETURN + "rows 0" + self.RETURN
+ self.disable_paging(command=cmd)
+
+ def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def check_config_mode(self, check_string: str = "*>", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "set -privilege diagnostic -confirmations off",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self,
+ exit_config: str = "set -privilege admin -confirmations off",
+ pattern: str = "",
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+
+
+
+
+
+
+class NetAppcDotSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetAppcDotSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ cmd = self.RETURN + "rows 0" + self.RETURN
+ self.disable_paging(command=cmd)
+
+ def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def check_config_mode(self, check_string: str = "*>", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "set -privilege diagnostic -confirmations off",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self,
+ exit_config: str = "set -privilege admin -confirmations off",
+ pattern: str = "",
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+Ancestors
+
+Methods
+
+
+def send_command_with_y(self, *args, **kwargs)
+
+-
+
+
+Source code
+def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ cmd = self.RETURN + "rows 0" + self.RETURN
+ self.disable_paging(command=cmd)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/netgear/index.html b/docs/netmiko/netgear/index.html
new file mode 100644
index 000000000..a78c2f82b
--- /dev/null
+++ b/docs/netmiko/netgear/index.html
@@ -0,0 +1,323 @@
+
+
+
+
+
+
+netmiko.netgear API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.netgear
+
+
+
+Source code
+from netmiko.netgear.netgear_prosafe_ssh import NetgearProSafeSSH
+
+__all__ = ["NetgearProSafeSSH"]
+
+
+
+
+
+
+
+
+
+class NetgearProSafeSSH
+(**kwargs)
+
+-
+
ProSafe OS support
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetgearProSafeSSH(CiscoSSHConnection):
+ """ProSafe OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(
+ self, check_string: str = "(Config)#", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"\#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ save_cmd: str = "write memory confirm",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ """ProSafe doesn't allow saving whilst within configuration mode"""
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ return super().save_config(
+ cmd=save_cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
ProSafe OS requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/netgear/netgear_prosafe_ssh.html b/docs/netmiko/netgear/netgear_prosafe_ssh.html
new file mode 100644
index 000000000..d7927eddc
--- /dev/null
+++ b/docs/netmiko/netgear/netgear_prosafe_ssh.html
@@ -0,0 +1,367 @@
+
+
+
+
+
+
+netmiko.netgear.netgear_prosafe_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.netgear.netgear_prosafe_ssh
+
+
+ProSafe OS support
+
+Source code
+"""ProSafe OS support"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class NetgearProSafeSSH(CiscoSSHConnection):
+ """ProSafe OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(
+ self, check_string: str = "(Config)#", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"\#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ save_cmd: str = "write memory confirm",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ """ProSafe doesn't allow saving whilst within configuration mode"""
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ return super().save_config(
+ cmd=save_cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class NetgearProSafeSSH
+(**kwargs)
+
+-
+
ProSafe OS support
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class NetgearProSafeSSH(CiscoSSHConnection):
+ """ProSafe OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(
+ self, check_string: str = "(Config)#", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"\#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ save_cmd: str = "write memory confirm",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ """ProSafe doesn't allow saving whilst within configuration mode"""
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ return super().save_config(
+ cmd=save_cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
ProSafe OS requires enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/netmiko_globals.html b/docs/netmiko/netmiko_globals.html
new file mode 100644
index 000000000..ed9d9d903
--- /dev/null
+++ b/docs/netmiko/netmiko_globals.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+netmiko.netmiko_globals API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.netmiko_globals
+
+
+
+Source code
+MAX_BUFFER = 65535
+BACKSPACE_CHAR = "\x08"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/no_config.html b/docs/netmiko/no_config.html
new file mode 100644
index 000000000..90deeb026
--- /dev/null
+++ b/docs/netmiko/no_config.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+netmiko.no_config API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.no_config
+
+
+
+Source code
+class NoConfig:
+ """
+ Class for platforms that have no config mode.
+
+ check_config_mode returns True as the expectation is that configuration commands
+ can be executed directly. So in your current state, you are in "config mode" i.e.
+ you can make configuration changes.
+
+ If you truly cannot make any configuration changes to device then you should probably
+ overwrite check_config_mode in the platform specific driver and return False.
+ """
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ return True
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return ""
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ return ""
+
+
+
+
+
+
+
+
+
+class NoConfig
+(*args, **kwargs)
+
+-
+
Class for platforms that have no config mode.
+check_config_mode returns True as the expectation is that configuration commands
+can be executed directly. So in your current state, you are in "config mode" i.e.
+you can make configuration changes.
+If you truly cannot make any configuration changes to device then you should probably
+overwrite check_config_mode in the platform specific driver and return False.
+
+Source code
+class NoConfig:
+ """
+ Class for platforms that have no config mode.
+
+ check_config_mode returns True as the expectation is that configuration commands
+ can be executed directly. So in your current state, you are in "config mode" i.e.
+ you can make configuration changes.
+
+ If you truly cannot make any configuration changes to device then you should probably
+ overwrite check_config_mode in the platform specific driver and return False.
+ """
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ return True
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return ""
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ return ""
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='', pattern='')
+
+-
+
+
+Source code
+def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ return True
+
+
+
+def config_mode(self, config_command='', pattern='', re_flags=0)
+
+-
+
+
+Source code
+def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+) -> str:
+ return ""
+
+
+
+def exit_config_mode(self, exit_config='', pattern='')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ return ""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/no_enable.html b/docs/netmiko/no_enable.html
new file mode 100644
index 000000000..6e122505c
--- /dev/null
+++ b/docs/netmiko/no_enable.html
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+netmiko.no_enable API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.no_enable
+
+
+
+Source code
+from typing import Optional
+import re
+
+
+class NoEnable:
+ """
+ Class for platforms that have no enable mode.
+
+ Netmiko translates the meaning of "enable" mode to be a proxy for "can
+ go into config mode". In other words, that you ultimately have privileges
+ to execute configuration changes.
+
+ The expectation on platforms that have no method for elevating privileges
+ is that the standard default privileges allow configuration changes.
+
+ Consequently check_enable_mode returns True by default for platforms that
+ don't explicitly support enable mode.
+ """
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ return True
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return ""
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ return ""
+
+
+
+
+
+
+
+
+
+class NoEnable
+(*args, **kwargs)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+
+Source code
+class NoEnable:
+ """
+ Class for platforms that have no enable mode.
+
+ Netmiko translates the meaning of "enable" mode to be a proxy for "can
+ go into config mode". In other words, that you ultimately have privileges
+ to execute configuration changes.
+
+ The expectation on platforms that have no method for elevating privileges
+ is that the standard default privileges allow configuration changes.
+
+ Consequently check_enable_mode returns True by default for platforms that
+ don't explicitly support enable mode.
+ """
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ return True
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return ""
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ return ""
+
+Subclasses
+
+Methods
+
+
+def check_enable_mode(self, check_string='')
+
+-
+
+
+Source code
+def check_enable_mode(self, check_string: str = "") -> bool:
+ return True
+
+
+
+def enable(self, cmd='', pattern='', enable_pattern=None, re_flags=)
+
+-
+
+
+Source code
+def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ return ""
+
+
+
+def exit_enable_mode(self, exit_command='')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "") -> str:
+ return ""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/nokia/index.html b/docs/netmiko/nokia/index.html
new file mode 100644
index 000000000..7693616a1
--- /dev/null
+++ b/docs/netmiko/nokia/index.html
@@ -0,0 +1,652 @@
+
+
+
+
+
+
+netmiko.nokia API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.nokia.nokia_sros import (
+ NokiaSrosSSH,
+ NokiaSrosTelnet,
+ NokiaSrosFileTransfer,
+)
+
+__all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer", "NokiaSrosTelnet"]
+
+
+
+
+
+
+
+
+
+class NokiaSrosFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=False)
+
+-
+
Class to manage SCP file transfer and associated SSH control channel.
+
+Source code
+class NokiaSrosFileTransfer(BaseFileTransfer):
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def _file_cmd_prefix(self) -> str:
+ """
+ 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: str = r"(\d+)\s+\w+\s+free"
+ ) -> int:
+ """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_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ assert match is not None
+ return int(match.group(1))
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Unexpected value for self.direction")
+ 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_str(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) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def compare_md5(self) -> bool:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ 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: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+
+
+def verify_file(self)
+
+-
+
Verify the file has been transferred correctly based on filesize.
+
+Source code
+def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+
+
+Inherited members
+
+
+
+class NokiaSrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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/nokia/nokia_sros.html b/docs/netmiko/nokia/nokia_sros.html
new file mode 100644
index 000000000..ad7f7f1ac
--- /dev/null
+++ b/docs/netmiko/nokia/nokia_sros.html
@@ -0,0 +1,1678 @@
+
+
+
+
+
+
+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 typing import Any, Optional, Union, Sequence, TextIO, Callable
+
+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) -> None:
+ 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: Any, **kwargs: Any) -> str:
+ """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: str = match.group(1)
+
+ return self.base_prompt
+
+ def _disable_complete_on_space(self) -> str:
+ """
+ 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: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """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: str = "in admin mode") -> bool:
+ """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", read_entire_line=True
+ )
+ if "ssword" in output:
+ self.write_channel(self.RETURN) # send ENTER to pass the password prompt
+ self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def exit_enable_mode(self, *args: Any, **kwargs: Any) -> str:
+ """Nokia SR OS does not have a notion of exiting administrative mode"""
+ return ""
+
+ def config_mode(
+ self,
+ config_command: str = "edit-config exclusive",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Enable config edit-mode for Nokia SR OS"""
+ output = ""
+ if not pattern:
+ pattern = rf"\(ex\)\[.*{self.base_prompt}.*$"
+ re_flags = re.DOTALL
+ # Only model-driven CLI supports config-mode
+ if "@" in self.base_prompt:
+ output += super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+ return output
+
+ def exit_config_mode(self, *args: Any, **kwargs: Any) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def check_config_mode(
+ self, check_string: str = r"(ex)[", pattern: str = r"@"
+ ) -> bool:
+ """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: Any, **kwargs: Any) -> str:
+ """Persist configuration to cflash for Nokia SR OS"""
+ return self._send_command_str(command_string="/admin save", expect_string=r"#")
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = None,
+ **kwargs: Any,
+ ) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """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) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ return output
+
+ def _discard(self) -> str:
+ """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(read_entire_line=True)
+ output += new_output
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """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: str = "logout") -> None:
+ """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: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def _file_cmd_prefix(self) -> str:
+ """
+ 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: str = r"(\d+)\s+\w+\s+free"
+ ) -> int:
+ """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_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ assert match is not None
+ return int(match.group(1))
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Unexpected value for self.direction")
+ 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_str(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) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def compare_md5(self) -> bool:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+
+
+
+
+
+
+
+
+class NokiaSros
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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) -> None:
+ 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: Any, **kwargs: Any) -> str:
+ """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: str = match.group(1)
+
+ return self.base_prompt
+
+ def _disable_complete_on_space(self) -> str:
+ """
+ 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: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """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: str = "in admin mode") -> bool:
+ """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", read_entire_line=True
+ )
+ if "ssword" in output:
+ self.write_channel(self.RETURN) # send ENTER to pass the password prompt
+ self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def exit_enable_mode(self, *args: Any, **kwargs: Any) -> str:
+ """Nokia SR OS does not have a notion of exiting administrative mode"""
+ return ""
+
+ def config_mode(
+ self,
+ config_command: str = "edit-config exclusive",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Enable config edit-mode for Nokia SR OS"""
+ output = ""
+ if not pattern:
+ pattern = rf"\(ex\)\[.*{self.base_prompt}.*$"
+ re_flags = re.DOTALL
+ # Only model-driven CLI supports config-mode
+ if "@" in self.base_prompt:
+ output += super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+ return output
+
+ def exit_config_mode(self, *args: Any, **kwargs: Any) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def check_config_mode(
+ self, check_string: str = r"(ex)[", pattern: str = r"@"
+ ) -> bool:
+ """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: Any, **kwargs: Any) -> str:
+ """Persist configuration to cflash for Nokia SR OS"""
+ return self._send_command_str(command_string="/admin save", expect_string=r"#")
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = None,
+ **kwargs: Any,
+ ) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """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) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ return output
+
+ def _discard(self) -> str:
+ """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(read_entire_line=True)
+ output += new_output
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """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: str = "logout") -> None:
+ """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: str = r"(ex)[", pattern: str = r"@"
+) -> bool:
+ """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')
+
+-
+
+
+Source code
+def check_enable_mode(self, check_string: str = "in admin mode") -> bool:
+ """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", read_entire_line=True
+ )
+ if "ssword" in output:
+ self.write_channel(self.RETURN) # send ENTER to pass the password prompt
+ self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+
+
+def cleanup(self, command='logout')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "logout") -> None:
+ """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: Any, **kwargs: Any) -> str:
+ """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='', re_flags=0)
+
+-
+
Enable config edit-mode for Nokia SR OS
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "edit-config exclusive",
+ pattern: str = "",
+ re_flags: int = 0,
+) -> str:
+ """Enable config edit-mode for Nokia SR OS"""
+ output = ""
+ if not pattern:
+ pattern = rf"\(ex\)\[.*{self.base_prompt}.*$"
+ re_flags = re.DOTALL
+ # Only model-driven CLI supports config-mode
+ if "@" in self.base_prompt:
+ output += super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+ return output
+
+
+
+def enable(self, cmd='enable', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
Enable SR OS administrative mode
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ 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: Any, **kwargs: Any) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """Persist configuration to cflash for Nokia SR OS"""
+ return self._send_command_str(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: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = None,
+ **kwargs: Any,
+) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """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: str = 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: Any, **kwargs: Any) -> str:
+ """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, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=False)
+
+-
+
Class to manage SCP file transfer and associated SSH control channel.
+
+Source code
+class NokiaSrosFileTransfer(BaseFileTransfer):
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def _file_cmd_prefix(self) -> str:
+ """
+ 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: str = r"(\d+)\s+\w+\s+free"
+ ) -> int:
+ """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_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ assert match is not None
+ return int(match.group(1))
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Unexpected value for self.direction")
+ 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_str(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) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def compare_md5(self) -> bool:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ 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: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+
+
+def verify_file(self)
+
+-
+
Verify the file has been transferred correctly based on filesize.
+
+Source code
+def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+
+
+Inherited members
+
+
+
+class NokiaSrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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/nokia/nokia_sros_ssh.html b/docs/netmiko/nokia/nokia_sros_ssh.html
new file mode 100644
index 000000000..0f59ad2de
--- /dev/null
+++ b/docs/netmiko/nokia/nokia_sros_ssh.html
@@ -0,0 +1,1196 @@
+
+
+
+
+
+
+netmiko.nokia.nokia_sros_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.nokia.nokia_sros_ssh
+
+
+
+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 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.
+
+ 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 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")
+
+ # Parse dir output for filename. Output format is:
+ # "10/16/2019 10:00p 6738 {filename}"
+
+ pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(remote_file))
+ 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.")
+
+
+
+
+
+
+
+
+
+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")
+
+ # Parse dir output for filename. Output format is:
+ # "10/16/2019 10:00p 6738 {filename}"
+
+ pattern = r"\S+\s+\S+\s+(\d+)\s+{}".format(re.escape(remote_file))
+ 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)
+
+-
+
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()
+ 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(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.
+
+ 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
+
+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')
+
+-
+
+
+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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/oneaccess/index.html b/docs/netmiko/oneaccess/index.html
new file mode 100644
index 000000000..612cc8cd3
--- /dev/null
+++ b/docs/netmiko/oneaccess/index.html
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+netmiko.oneaccess API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.oneaccess
+
+
+
+Source code
+from netmiko.oneaccess.oneaccess_oneos import OneaccessOneOSSSH, OneaccessOneOSTelnet
+
+__all__ = ["OneaccessOneOSSSH", "OneaccessOneOSTelnet"]
+
+
+
+
+
+
+
+
+
+class OneaccessOneOSSSH
+(*args, **kwargs)
+
+-
+
Base Class for cisco-like behavior.
+Init connection - similar as Cisco
+
+Source code
+class OneaccessOneOSSSH(OneaccessOneOSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class OneaccessOneOSTelnet
+(*args, **kwargs)
+
+-
+
Base Class for cisco-like behavior.
+Init connection - similar as Cisco
+
+Source code
+class OneaccessOneOSTelnet(OneaccessOneOSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/oneaccess/oneaccess_oneos.html b/docs/netmiko/oneaccess/oneaccess_oneos.html
new file mode 100644
index 000000000..1d89ad497
--- /dev/null
+++ b/docs/netmiko/oneaccess/oneaccess_oneos.html
@@ -0,0 +1,378 @@
+
+
+
+
+
+
+netmiko.oneaccess.oneaccess_oneos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.oneaccess.oneaccess_oneos
+
+
+Netmiko driver for OneAccess ONEOS
+
+Source code
+"""Netmiko driver for OneAccess ONEOS"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class OneaccessOneOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Init connection - similar as Cisco"""
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare connection - disable paging"""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="stty columns 255", pattern="stty")
+ self.disable_paging(command="term len 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write mem"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class OneaccessOneOSSSH(OneaccessOneOSBase):
+ pass
+
+
+class OneaccessOneOSTelnet(OneaccessOneOSBase):
+ pass
+
+
+
+
+
+
+
+
+
+class OneaccessOneOSBase
+(*args, **kwargs)
+
+-
+
Base Class for cisco-like behavior.
+Init connection - similar as Cisco
+
+Source code
+class OneaccessOneOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Init connection - similar as Cisco"""
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare connection - disable paging"""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="stty columns 255", pattern="stty")
+ self.disable_paging(command="term len 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write mem"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write mem', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Save config: write mem"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def session_preparation(self)
+
+-
+
Prepare connection - disable paging
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare connection - disable paging"""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="stty columns 255", pattern="stty")
+ self.disable_paging(command="term len 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class OneaccessOneOSSSH
+(*args, **kwargs)
+
+-
+
Base Class for cisco-like behavior.
+Init connection - similar as Cisco
+
+Source code
+class OneaccessOneOSSSH(OneaccessOneOSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class OneaccessOneOSTelnet
+(*args, **kwargs)
+
+-
+
Base Class for cisco-like behavior.
+Init connection - similar as Cisco
+
+Source code
+class OneaccessOneOSTelnet(OneaccessOneOSBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ovs/index.html b/docs/netmiko/ovs/index.html
new file mode 100644
index 000000000..b4c57ddae
--- /dev/null
+++ b/docs/netmiko/ovs/index.html
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+netmiko.ovs API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.ovs.ovs_linux_ssh import OvsLinuxSSH
+
+__all__ = ["OvsLinuxSSH"]
+
+
+
+
+
+
+
+
+
+class OvsLinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class OvsLinuxSSH(LinuxSSH):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ovs/ovs_linux_ssh.html b/docs/netmiko/ovs/ovs_linux_ssh.html
new file mode 100644
index 000000000..848615588
--- /dev/null
+++ b/docs/netmiko/ovs/ovs_linux_ssh.html
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+netmiko.ovs.ovs_linux_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ovs.ovs_linux_ssh
+
+
+
+Source code
+from netmiko.linux.linux_ssh import LinuxSSH
+
+
+class OvsLinuxSSH(LinuxSSH):
+ pass
+
+
+
+
+
+
+
+
+
+class OvsLinuxSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class OvsLinuxSSH(LinuxSSH):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/paloalto/index.html b/docs/netmiko/paloalto/index.html
new file mode 100644
index 000000000..bea5de377
--- /dev/null
+++ b/docs/netmiko/paloalto/index.html
@@ -0,0 +1,448 @@
+
+
+
+
+
+
+netmiko.paloalto API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.paloalto
+
+
+
+Source code
+from netmiko.paloalto.paloalto_panos import PaloAltoPanosSSH, PaloAltoPanosTelnet
+
+__all__ = ["PaloAltoPanosSSH", "PaloAltoPanosTelnet"]
+
+
+
+
+
+
+
+
+
+class PaloAltoPanosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with PaloAlto devices.
+Disables enable() and check_enable_mode()
+methods.
+Overrides several methods for PaloAlto-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class PaloAltoPanosSSH(PaloAltoPanosBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_interactive()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class PaloAltoPanosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with PaloAlto devices.
+Disables enable() and check_enable_mode()
+methods.
+Overrides several methods for PaloAlto-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class PaloAltoPanosTelnet(PaloAltoPanosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/paloalto/paloalto_panos.html b/docs/netmiko/paloalto/paloalto_panos.html
new file mode 100644
index 000000000..782396800
--- /dev/null
+++ b/docs/netmiko/paloalto/paloalto_panos.html
@@ -0,0 +1,1389 @@
+
+
+
+
+
+
+netmiko.paloalto.paloalto_panos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.paloalto.paloalto_panos
+
+
+
+Source code
+from typing import Optional, List, Any, Tuple
+import re
+import warnings
+from os import path
+from paramiko import SSHClient, Transport
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class SSHClient_interactive(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def pa_banner_handler(
+ self, title: str, instructions: str, prompt_list: List[Tuple[str, bool]]
+ ) -> List[str]:
+
+ resp = []
+ for prompt, echo in prompt_list:
+ if "Do you accept" in prompt:
+ resp.append("yes")
+ elif "ssword" in prompt:
+ assert isinstance(self.password, str)
+ resp.append(self.password)
+ return resp
+
+ def _auth(self, username: str, password: str, *args: Any) -> None:
+ """
+ _auth: args as of aug-2021
+ self,
+ username,
+ password,
+ pkey,
+ key_filenames,
+ allow_agent,
+ look_for_keys,
+ gss_auth,
+ gss_kex,
+ gss_deleg_creds,
+ gss_host,
+ passphrase,
+ """
+
+ # Just gets the password up to the pa_banner_handler
+ self.password = password
+ transport = self.get_transport()
+ assert isinstance(transport, Transport)
+ transport.auth_interactive(username, handler=self.pa_banner_handler)
+ return
+
+
+class PaloAltoPanosBase(NoEnable, BaseConnection):
+ """
+ Implement methods for interacting with PaloAlto devices.
+
+ Disables `enable()` and `check_enable_mode()`
+ methods. Overrides several methods for PaloAlto-specific compatibility.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.disable_paging(
+ command="set cli scripting-mode on", cmd_verify=False, pattern=r" on"
+ )
+ self.set_terminal_width(
+ command="set cli terminal width 500", pattern=r"set cli terminal width 500"
+ )
+ self.disable_paging(command="set cli pager off")
+ self.set_base_prompt()
+
+ # PA devices can be really slow--try to make sure we are caught up
+ self.write_channel("show admins\n")
+ self._test_channel_read(pattern=r"Client")
+ self._test_channel_read(pattern=r"[>#]")
+
+ def find_prompt(
+ self, delay_factor: float = 5.0, pattern: Optional[str] = None
+ ) -> str:
+ """PA devices can be very slow to respond (in certain situations)"""
+ return super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = r"#", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def commit(
+ self,
+ comment: str = "",
+ force: bool = False,
+ partial: bool = False,
+ device_and_network: bool = False,
+ policy_and_objects: bool = False,
+ vsys: str = "",
+ no_vsys: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ (device_and_network or policy_and_objects or vsys or
+ no_vsys) and not partial:
+ Exception
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if (
+ device_and_network or policy_and_objects or vsys or no_vsys
+ ) and not partial:
+ raise ValueError(
+ "'partial' must be True when using "
+ "device_and_network or policy_and_objects "
+ "or vsys or no_vsys."
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "configuration committed successfully"
+ if comment:
+ command_string += f' description "{comment}"'
+ if force:
+ command_string += " force"
+ if partial:
+ command_string += " partial"
+ if vsys:
+ command_string += f" {vsys}"
+ if device_and_network:
+ command_string += " device-and-network"
+ if policy_and_objects:
+ command_string += " device-and-network"
+ if no_vsys:
+ command_string += " no-vsys"
+ command_string += " excluded"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ expect_string="100%",
+ read_timeout=read_timeout,
+ )
+ output += self.exit_config_mode()
+
+ if commit_marker not in output.lower():
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ return output
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """Strip command_string from output string."""
+ output_list = output.split(command_string)
+ return self.RESPONSE_RETURN.join(output_list)
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ new_response_list = []
+ for line in response_list:
+ if self.base_prompt not in line:
+ new_response_list.append(line)
+
+ output = self.RESPONSE_RETURN.join(new_response_list)
+ return self.strip_context_items(output)
+
+ def strip_context_items(self, a_string: str) -> str:
+ """Strip PaloAlto-specific output.
+
+ PaloAlto will also put a configuration context:
+ [edit]
+
+ This method removes those lines.
+ """
+ strings_to_strip = [r"\[edit.*\]"]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+
+ return a_string
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+
+class PaloAltoPanosSSH(PaloAltoPanosBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_interactive()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+
+class PaloAltoPanosTelnet(PaloAltoPanosBase):
+ pass
+
+
+
+
+
+
+
+
+
+class PaloAltoPanosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with PaloAlto devices.
+Disables enable() and check_enable_mode()
+methods.
+Overrides several methods for PaloAlto-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class PaloAltoPanosBase(NoEnable, BaseConnection):
+ """
+ Implement methods for interacting with PaloAlto devices.
+
+ Disables `enable()` and `check_enable_mode()`
+ methods. Overrides several methods for PaloAlto-specific compatibility.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.disable_paging(
+ command="set cli scripting-mode on", cmd_verify=False, pattern=r" on"
+ )
+ self.set_terminal_width(
+ command="set cli terminal width 500", pattern=r"set cli terminal width 500"
+ )
+ self.disable_paging(command="set cli pager off")
+ self.set_base_prompt()
+
+ # PA devices can be really slow--try to make sure we are caught up
+ self.write_channel("show admins\n")
+ self._test_channel_read(pattern=r"Client")
+ self._test_channel_read(pattern=r"[>#]")
+
+ def find_prompt(
+ self, delay_factor: float = 5.0, pattern: Optional[str] = None
+ ) -> str:
+ """PA devices can be very slow to respond (in certain situations)"""
+ return super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = r"#", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def commit(
+ self,
+ comment: str = "",
+ force: bool = False,
+ partial: bool = False,
+ device_and_network: bool = False,
+ policy_and_objects: bool = False,
+ vsys: str = "",
+ no_vsys: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ (device_and_network or policy_and_objects or vsys or
+ no_vsys) and not partial:
+ Exception
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if (
+ device_and_network or policy_and_objects or vsys or no_vsys
+ ) and not partial:
+ raise ValueError(
+ "'partial' must be True when using "
+ "device_and_network or policy_and_objects "
+ "or vsys or no_vsys."
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "configuration committed successfully"
+ if comment:
+ command_string += f' description "{comment}"'
+ if force:
+ command_string += " force"
+ if partial:
+ command_string += " partial"
+ if vsys:
+ command_string += f" {vsys}"
+ if device_and_network:
+ command_string += " device-and-network"
+ if policy_and_objects:
+ command_string += " device-and-network"
+ if no_vsys:
+ command_string += " no-vsys"
+ command_string += " excluded"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ expect_string="100%",
+ read_timeout=read_timeout,
+ )
+ output += self.exit_config_mode()
+
+ if commit_marker not in output.lower():
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ return output
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """Strip command_string from output string."""
+ output_list = output.split(command_string)
+ return self.RESPONSE_RETURN.join(output_list)
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ new_response_list = []
+ for line in response_list:
+ if self.base_prompt not in line:
+ new_response_list.append(line)
+
+ output = self.RESPONSE_RETURN.join(new_response_list)
+ return self.strip_context_items(output)
+
+ def strip_context_items(self, a_string: str) -> str:
+ """Strip PaloAlto-specific output.
+
+ PaloAlto will also put a configuration context:
+ [edit]
+
+ This method removes those lines.
+ """
+ strings_to_strip = [r"\[edit.*\]"]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+
+ return a_string
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+Ancestors
+
+Subclasses
+
+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: str = "]", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def cleanup(self, command='exit')
+
+-
+
Gracefully exit the SSH session.
+
+Source code
+def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+
+
+def commit(self, comment='', force=False, partial=False, device_and_network=False, policy_and_objects=False, vsys='', no_vsys=False, read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+Commit the entered configuration. Raise an error and return the failure
+if the commit fails.
+Automatically enters configuration mode
+default:
+command_string = commit
+(device_and_network or policy_and_objects or vsys or
+no_vsys) and not partial:
+Exception
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ force: bool = False,
+ partial: bool = False,
+ device_and_network: bool = False,
+ policy_and_objects: bool = False,
+ vsys: str = "",
+ no_vsys: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ (device_and_network or policy_and_objects or vsys or
+ no_vsys) and not partial:
+ Exception
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if (
+ device_and_network or policy_and_objects or vsys or no_vsys
+ ) and not partial:
+ raise ValueError(
+ "'partial' must be True when using "
+ "device_and_network or policy_and_objects "
+ "or vsys or no_vsys."
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "configuration committed successfully"
+ if comment:
+ command_string += f' description "{comment}"'
+ if force:
+ command_string += " force"
+ if partial:
+ command_string += " partial"
+ if vsys:
+ command_string += f" {vsys}"
+ if device_and_network:
+ command_string += " device-and-network"
+ if policy_and_objects:
+ command_string += " device-and-network"
+ if no_vsys:
+ command_string += " no-vsys"
+ command_string += " excluded"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ expect_string="100%",
+ read_timeout=read_timeout,
+ )
+ output += self.exit_config_mode()
+
+ if commit_marker not in output.lower():
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ return output
+
+
+
+def config_mode(self, config_command='configure', pattern='#', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = r"#", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='>')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def find_prompt(self, delay_factor=5.0, pattern=None)
+
+-
+
PA devices can be very slow to respond (in certain situations)
+
+Source code
+def find_prompt(
+ self, delay_factor: float = 5.0, pattern: Optional[str] = None
+) -> str:
+ """PA devices can be very slow to respond (in certain situations)"""
+ return super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+
+
+
+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) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.disable_paging(
+ command="set cli scripting-mode on", cmd_verify=False, pattern=r" on"
+ )
+ self.set_terminal_width(
+ command="set cli terminal width 500", pattern=r"set cli terminal width 500"
+ )
+ self.disable_paging(command="set cli pager off")
+ self.set_base_prompt()
+
+ # PA devices can be really slow--try to make sure we are caught up
+ self.write_channel("show admins\n")
+ self._test_channel_read(pattern=r"Client")
+ self._test_channel_read(pattern=r"[>#]")
+
+
+
+def strip_command(self, command_string, output)
+
+-
+
Strip command_string from output string.
+
+Source code
+def strip_command(self, command_string: str, output: str) -> str:
+ """Strip command_string from output string."""
+ output_list = output.split(command_string)
+ return self.RESPONSE_RETURN.join(output_list)
+
+
+
+def strip_context_items(self, a_string)
+
+-
+
Strip PaloAlto-specific output.
+PaloAlto will also put a configuration context:
+[edit]
+This method removes those lines.
+
+Source code
+def strip_context_items(self, a_string: str) -> str:
+ """Strip PaloAlto-specific output.
+
+ PaloAlto will also put a configuration context:
+ [edit]
+
+ This method removes those lines.
+ """
+ strings_to_strip = [r"\[edit.*\]"]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+
+ return a_string
+
+
+
+def strip_prompt(self, a_string)
+
+-
+
Strip the trailing router prompt from the output.
+
+Source code
+def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ new_response_list = []
+ for line in response_list:
+ if self.base_prompt not in line:
+ new_response_list.append(line)
+
+ output = self.RESPONSE_RETURN.join(new_response_list)
+ return self.strip_context_items(output)
+
+
+
+Inherited members
+
+
+
+class PaloAltoPanosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with PaloAlto devices.
+Disables enable() and check_enable_mode()
+methods.
+Overrides several methods for PaloAlto-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class PaloAltoPanosSSH(PaloAltoPanosBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_interactive()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+Ancestors
+
+Inherited members
+
+
+
+class PaloAltoPanosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with PaloAlto devices.
+Disables enable() and check_enable_mode()
+methods.
+Overrides several methods for PaloAlto-specific compatibility.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class PaloAltoPanosTelnet(PaloAltoPanosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class SSHClient_interactive
+
+-
+
Set noauth when manually handling SSH authentication.
+Create a new SSHClient.
+
+Source code
+class SSHClient_interactive(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def pa_banner_handler(
+ self, title: str, instructions: str, prompt_list: List[Tuple[str, bool]]
+ ) -> List[str]:
+
+ resp = []
+ for prompt, echo in prompt_list:
+ if "Do you accept" in prompt:
+ resp.append("yes")
+ elif "ssword" in prompt:
+ assert isinstance(self.password, str)
+ resp.append(self.password)
+ return resp
+
+ def _auth(self, username: str, password: str, *args: Any) -> None:
+ """
+ _auth: args as of aug-2021
+ self,
+ username,
+ password,
+ pkey,
+ key_filenames,
+ allow_agent,
+ look_for_keys,
+ gss_auth,
+ gss_kex,
+ gss_deleg_creds,
+ gss_host,
+ passphrase,
+ """
+
+ # Just gets the password up to the pa_banner_handler
+ self.password = password
+ transport = self.get_transport()
+ assert isinstance(transport, Transport)
+ transport.auth_interactive(username, handler=self.pa_banner_handler)
+ return
+
+Ancestors
+
+- paramiko.client.SSHClient
+- paramiko.util.ClosingContextManager
+
+Methods
+
+
+def pa_banner_handler(self, title, instructions, prompt_list)
+
+-
+
+
+Source code
+def pa_banner_handler(
+ self, title: str, instructions: str, prompt_list: List[Tuple[str, bool]]
+) -> List[str]:
+
+ resp = []
+ for prompt, echo in prompt_list:
+ if "Do you accept" in prompt:
+ resp.append("yes")
+ elif "ssword" in prompt:
+ assert isinstance(self.password, str)
+ resp.append(self.password)
+ return resp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/pluribus/index.html b/docs/netmiko/pluribus/index.html
new file mode 100644
index 000000000..3f5d5306a
--- /dev/null
+++ b/docs/netmiko/pluribus/index.html
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+netmiko.pluribus API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.pluribus
+
+
+
+Source code
+# -*- coding: utf-8 -*-
+from netmiko.pluribus.pluribus_ssh import PluribusSSH
+
+__all__ = ("PluribusSSH",)
+
+
+
+
+
+
+
+
+
+class PluribusSSH
+(*args, **kwargs)
+
+-
+
Common methods for Pluribus.
+
+Source code
+class PluribusSSH(NoConfig, BaseConnection):
+ """Common methods for Pluribus."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ super().__init__(*args, **kwargs)
+ self._config_mode = False
+
+ def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the netmiko session.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/pluribus/pluribus_ssh.html b/docs/netmiko/pluribus/pluribus_ssh.html
new file mode 100644
index 000000000..f9885b8cd
--- /dev/null
+++ b/docs/netmiko/pluribus/pluribus_ssh.html
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+netmiko.pluribus.pluribus_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.pluribus.pluribus_ssh
+
+
+
+Source code
+import time
+from typing import Any
+
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class PluribusSSH(NoConfig, BaseConnection):
+ """Common methods for Pluribus."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ super().__init__(*args, **kwargs)
+ self._config_mode = False
+
+ def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+
+
+
+
+
+
+class PluribusSSH
+(*args, **kwargs)
+
+-
+
Common methods for Pluribus.
+
+Source code
+class PluribusSSH(NoConfig, BaseConnection):
+ """Common methods for Pluribus."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ super().__init__(*args, **kwargs)
+ self._config_mode = False
+
+ def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the netmiko session.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/py23_compat.html b/docs/netmiko/py23_compat.html
new file mode 100644
index 000000000..a3d8d4557
--- /dev/null
+++ b/docs/netmiko/py23_compat.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+netmiko.py23_compat API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.py23_compat
+
+
+Simplify Python3 compatibility. Modeled after six behavior for small set of things
+
+Source code
+"""Simplify Python3 compatibility. Modeled after six behavior for small set of things"""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import io
+import sys
+
+PY2 = sys.version_info.major == 2
+PY3 = sys.version_info.major == 3
+
+if PY3:
+ string_types = (str,)
+ text_type = str
+ bufferedio_types = io.BufferedIOBase
+else:
+ string_types = (basestring,) # noqa
+ text_type = unicode # noqa
+ bufferedio_types = (io.BufferedIOBase, file) # noqa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/quanta/index.html b/docs/netmiko/quanta/index.html
new file mode 100644
index 000000000..abfa144d1
--- /dev/null
+++ b/docs/netmiko/quanta/index.html
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+netmiko.quanta API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.quanta.quanta_mesh_ssh import QuantaMeshSSH
+
+__all__ = ["QuantaMeshSSH"]
+
+
+
+
+
+
+
+
+
+class QuantaMeshSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class QuantaMeshSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging("no pager")
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/quanta/quanta_mesh_ssh.html b/docs/netmiko/quanta/quanta_mesh_ssh.html
new file mode 100644
index 000000000..e89fd5363
--- /dev/null
+++ b/docs/netmiko/quanta/quanta_mesh_ssh.html
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+netmiko.quanta.quanta_mesh_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.quanta.quanta_mesh_ssh
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class QuantaMeshSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging("no pager")
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class QuantaMeshSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class QuantaMeshSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging("no pager")
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Methods
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/rad/index.html b/docs/netmiko/rad/index.html
new file mode 100644
index 000000000..1d449b3f4
--- /dev/null
+++ b/docs/netmiko/rad/index.html
@@ -0,0 +1,495 @@
+
+
+
+
+
+
+netmiko.rad API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.rad.rad_etx import RadETXSSH
+from netmiko.rad.rad_etx import RadETXTelnet
+
+__all__ = ["RadETXSSH", "RadETXTelnet"]
+
+
+
+
+
+
+
+
+
+class RadETXSSH
+(**kwargs)
+
+-
+
RAD ETX SSH Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RadETXSSH(RadETXBase):
+ """RAD ETX SSH Support."""
+
+ def __init__(self, **kwargs: Any) -> None:
+ # Found that a global_delay_factor of 2 is needed at minimum for SSH to the Rad ETX.
+ kwargs.setdefault("global_delay_factor", 2)
+ return super().__init__(**kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+class RadETXTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
RAD ETX Telnet Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RadETXTelnet(RadETXBase):
+ """RAD ETX Telnet Support."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='#\\s*$', username_pattern='(?:user>)', pwd_pattern='assword', delay_factor=1.0, max_loops=20)
+
+-
+
RAD presents with the following on login
+user>
+password> ****
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/rad/rad_etx.html b/docs/netmiko/rad/rad_etx.html
new file mode 100644
index 000000000..234846db8
--- /dev/null
+++ b/docs/netmiko/rad/rad_etx.html
@@ -0,0 +1,886 @@
+
+
+
+
+
+
+netmiko.rad.rad_etx API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.rad.rad_etx
+
+
+
+Source code
+import time
+from typing import Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection
+
+
+class RadETXBase(NoEnable, BaseConnection):
+ """RAD ETX Support, Tested on RAD 203AX, 205A and 220A."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="config term length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "admin save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using admin save."""
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config",
+ pattern: str = ">config",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter into configuration mode on remote device."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ">config", pattern: str = ""
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Rad config starts with baseprompt>config.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def exit_config_mode(
+ self, exit_config: str = "exit all", pattern: str = "#"
+ ) -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+class RadETXSSH(RadETXBase):
+ """RAD ETX SSH Support."""
+
+ def __init__(self, **kwargs: Any) -> None:
+ # Found that a global_delay_factor of 2 is needed at minimum for SSH to the Rad ETX.
+ kwargs.setdefault("global_delay_factor", 2)
+ return super().__init__(**kwargs)
+
+
+class RadETXTelnet(RadETXBase):
+ """RAD ETX Telnet Support."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+
+
+
+
+
+
+class RadETXBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
RAD ETX Support, Tested on RAD 203AX, 205A and 220A.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RadETXBase(NoEnable, BaseConnection):
+ """RAD ETX Support, Tested on RAD 203AX, 205A and 220A."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="config term length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "admin save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using admin save."""
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config",
+ pattern: str = ">config",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter into configuration mode on remote device."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ">config", pattern: str = ""
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Rad config starts with baseprompt>config.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def exit_config_mode(
+ self, exit_config: str = "exit all", pattern: str = "#"
+ ) -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='>config', pattern='')
+
+-
+
Checks if the device is in configuration mode or not.
+Rad config starts with baseprompt>config.
+
+Source code
+def check_config_mode(
+ self, check_string: str = ">config", pattern: str = ""
+) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Rad config starts with baseprompt>config.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def config_mode(self, config_command='config', pattern='>config', re_flags=0)
+
+-
+
Enter into configuration mode on remote device.
+
+Source code
+def config_mode(
+ self,
+ config_command: str = "config",
+ pattern: str = ">config",
+ re_flags: int = 0,
+) -> str:
+ """Enter into configuration mode on remote device."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit all', pattern='#')
+
+-
+
Exit from configuration mode.
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit all", pattern: str = "#"
+) -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def save_config(self, cmd='admin save', confirm=False, confirm_response='')
+
+-
+
Saves Config Using admin save.
+
+Source code
+def save_config(
+ self, cmd: str = "admin save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config Using admin save."""
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+
+
+Inherited members
+
+
+
+class RadETXSSH
+(**kwargs)
+
+-
+
RAD ETX SSH Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RadETXSSH(RadETXBase):
+ """RAD ETX SSH Support."""
+
+ def __init__(self, **kwargs: Any) -> None:
+ # Found that a global_delay_factor of 2 is needed at minimum for SSH to the Rad ETX.
+ kwargs.setdefault("global_delay_factor", 2)
+ return super().__init__(**kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+class RadETXTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
RAD ETX Telnet Support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RadETXTelnet(RadETXBase):
+ """RAD ETX Telnet Support."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#\\s*$', alt_prompt_terminator='#\\s*$', username_pattern='(?:user>)', pwd_pattern='assword', delay_factor=1.0, max_loops=20)
+
+-
+
RAD presents with the following on login
+user>
+password> ****
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/raisecom/index.html b/docs/netmiko/raisecom/index.html
new file mode 100644
index 000000000..d41a2d803
--- /dev/null
+++ b/docs/netmiko/raisecom/index.html
@@ -0,0 +1,574 @@
+
+
+
+
+
+
+netmiko.raisecom API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.raisecom
+
+
+
+Source code
+from netmiko.raisecom.raisecom_roap import RaisecomRoapSSH
+from netmiko.raisecom.raisecom_roap import RaisecomRoapTelnet
+
+__all__ = ["RaisecomRoapSSH", "RaisecomRoapTelnet"]
+
+
+
+
+
+
+
+
+
+class RaisecomRoapSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RaisecomRoapSSH(RaisecomRoapBase):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Raisecom presents with the following on login (in certain OS versions)
+Login: user
+Password:****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class RaisecomRoapTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RaisecomRoapTelnet(RaisecomRoapBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Weight:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(Login|Username)",
+ pwd_pattern: str = r"Password",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ self.write_channel(self.username + self.TELNET_RETURN)
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/raisecom/raisecom_roap.html b/docs/netmiko/raisecom/raisecom_roap.html
new file mode 100644
index 000000000..2fce28543
--- /dev/null
+++ b/docs/netmiko/raisecom/raisecom_roap.html
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+netmiko.raisecom.raisecom_roap API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.raisecom.raisecom_roap
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoBaseConnection
+import re
+import time
+from socket import socket
+
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, ECHO, SGA, NAWS, Telnet
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class RaisecomRoapBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging("terminal page-break disable")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ self.exit_config_mode()
+ self.enable()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class RaisecomRoapSSH(RaisecomRoapBase):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+class RaisecomRoapTelnet(RaisecomRoapBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Weight:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(Login|Username)",
+ pwd_pattern: str = r"Password",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ self.write_channel(self.username + self.TELNET_RETURN)
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+
+
+
+
+
+
+
+
+class RaisecomRoapBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RaisecomRoapBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging("terminal page-break disable")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ self.exit_config_mode()
+ self.enable()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging("terminal page-break disable")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class RaisecomRoapSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RaisecomRoapSSH(RaisecomRoapBase):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+Ancestors
+
+Methods
+
+
+def special_login_handler(self, delay_factor=1.0)
+
+-
+
Raisecom presents with the following on login (in certain OS versions)
+Login: user
+Password:****
+
+Source code
+def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+
+Inherited members
+
+
+
+class RaisecomRoapTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RaisecomRoapTelnet(RaisecomRoapBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Weight:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(Login|Username)",
+ pwd_pattern: str = r"Password",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ self.write_channel(self.username + self.TELNET_RETURN)
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ruckus/index.html b/docs/netmiko/ruckus/index.html
new file mode 100644
index 000000000..cec5ffe17
--- /dev/null
+++ b/docs/netmiko/ruckus/index.html
@@ -0,0 +1,447 @@
+
+
+
+
+
+
+netmiko.ruckus API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.ruckus.ruckus_fastiron import RuckusFastironSSH
+from netmiko.ruckus.ruckus_fastiron import RuckusFastironTelnet
+
+__all__ = ["RuckusFastironSSH", "RuckusFastironTelnet"]
+
+
+
+
+
+
+
+
+
+class RuckusFastironSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ruckus FastIron aka ICX support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuckusFastironSSH(RuckusFastironBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class RuckusFastironTelnet
+(*args, **kwargs)
+
+-
+
Ruckus FastIron aka ICX support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuckusFastironTelnet(RuckusFastironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ Ruckus FastIron/ICX does not always echo commands to output by default.
+ If server expresses interest in 'ECHO' option, then reply back with 'DO
+ ECHO'
+ """
+ if option == ECHO:
+ tsocket.sendall(IAC + DO + ECHO)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ruckus/ruckus_fastiron.html b/docs/netmiko/ruckus/ruckus_fastiron.html
new file mode 100644
index 000000000..12ac11086
--- /dev/null
+++ b/docs/netmiko/ruckus/ruckus_fastiron.html
@@ -0,0 +1,890 @@
+
+
+
+
+
+
+netmiko.ruckus.ruckus_fastiron API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ruckus.ruckus_fastiron
+
+
+
+Source code
+import re
+import time
+from socket import socket
+from typing import Optional, Any
+
+from telnetlib import DO, DONT, ECHO, IAC, WILL, WONT, Telnet
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class RuckusFastironBase(CiscoSSHConnection):
+ """Ruckus FastIron aka ICX support."""
+
+ def session_preparation(self) -> None:
+ """FastIron requires to be enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="skip-page-display")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"(ssword|User Name)",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode.
+ With RADIUS can prompt for User Name
+ SSH@Lab-ICX7250>en
+ User Name:service_netmiko
+ Password:
+ SSH@Lab-ICX7250#
+ """
+ output = ""
+ if not self.check_enable_mode():
+ count = 4
+ i = 1
+ while i < count:
+ self.write_channel(self.normalize_cmd(cmd))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "User Name" in new_data:
+ self.write_channel(self.normalize_cmd(self.username))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "ssword" in new_data:
+ self.write_channel(self.normalize_cmd(self.secret))
+ new_data = self.read_until_prompt(read_entire_line=True)
+ output += new_data
+ if not re.search(
+ r"error.*incorrect.*password", new_data, flags=re.I
+ ):
+ break
+
+ time.sleep(1)
+ i += 1
+
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+
+ return output
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class RuckusFastironTelnet(RuckusFastironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ Ruckus FastIron/ICX does not always echo commands to output by default.
+ If server expresses interest in 'ECHO' option, then reply back with 'DO
+ ECHO'
+ """
+ if option == ECHO:
+ tsocket.sendall(IAC + DO + ECHO)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+
+class RuckusFastironSSH(RuckusFastironBase):
+ pass
+
+
+
+
+
+
+
+
+
+class RuckusFastironBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ruckus FastIron aka ICX support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuckusFastironBase(CiscoSSHConnection):
+ """Ruckus FastIron aka ICX support."""
+
+ def session_preparation(self) -> None:
+ """FastIron requires to be enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="skip-page-display")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"(ssword|User Name)",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode.
+ With RADIUS can prompt for User Name
+ SSH@Lab-ICX7250>en
+ User Name:service_netmiko
+ Password:
+ SSH@Lab-ICX7250#
+ """
+ output = ""
+ if not self.check_enable_mode():
+ count = 4
+ i = 1
+ while i < count:
+ self.write_channel(self.normalize_cmd(cmd))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "User Name" in new_data:
+ self.write_channel(self.normalize_cmd(self.username))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "ssword" in new_data:
+ self.write_channel(self.normalize_cmd(self.secret))
+ new_data = self.read_until_prompt(read_entire_line=True)
+ output += new_data
+ if not re.search(
+ r"error.*incorrect.*password", new_data, flags=re.I
+ ):
+ break
+
+ time.sleep(1)
+ i += 1
+
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+
+ return output
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def enable(self, cmd='enable', pattern='(ssword|User Name)', enable_pattern=None, re_flags=)
+
+-
+
Enter enable mode.
+With RADIUS can prompt for User Name
+SSH@Lab-ICX7250>en
+User Name:service_netmiko
+Password:
+SSH@Lab-ICX7250#
+
+Source code
+def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"(ssword|User Name)",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """Enter enable mode.
+ With RADIUS can prompt for User Name
+ SSH@Lab-ICX7250>en
+ User Name:service_netmiko
+ Password:
+ SSH@Lab-ICX7250#
+ """
+ output = ""
+ if not self.check_enable_mode():
+ count = 4
+ i = 1
+ while i < count:
+ self.write_channel(self.normalize_cmd(cmd))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "User Name" in new_data:
+ self.write_channel(self.normalize_cmd(self.username))
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ output += new_data
+ if "ssword" in new_data:
+ self.write_channel(self.normalize_cmd(self.secret))
+ new_data = self.read_until_prompt(read_entire_line=True)
+ output += new_data
+ if not re.search(
+ r"error.*incorrect.*password", new_data, flags=re.I
+ ):
+ break
+
+ time.sleep(1)
+ i += 1
+
+ if not self.check_enable_mode():
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ raise ValueError(msg)
+
+ return output
+
+
+
+def save_config(self, cmd='write mem', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+def session_preparation(self)
+
+-
+
FastIron requires to be enable mode to disable paging.
+
+Source code
+def session_preparation(self) -> None:
+ """FastIron requires to be enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="skip-page-display")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class RuckusFastironSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Ruckus FastIron aka ICX support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuckusFastironSSH(RuckusFastironBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class RuckusFastironTelnet
+(*args, **kwargs)
+
+-
+
Ruckus FastIron aka ICX support.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuckusFastironTelnet(RuckusFastironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ Ruckus FastIron/ICX does not always echo commands to output by default.
+ If server expresses interest in 'ECHO' option, then reply back with 'DO
+ ECHO'
+ """
+ if option == ECHO:
+ tsocket.sendall(IAC + DO + ECHO)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ruijie/index.html b/docs/netmiko/ruijie/index.html
new file mode 100644
index 000000000..ec693b736
--- /dev/null
+++ b/docs/netmiko/ruijie/index.html
@@ -0,0 +1,426 @@
+
+
+
+
+
+
+netmiko.ruijie API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.ruijie.ruijie_os import RuijieOSSSH, RuijieOSTelnet
+
+__all__ = ["RuijieOSSSH", "RuijieOSTelnet"]
+
+
+
+
+
+
+
+
+
+class RuijieOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuijieOSSSH(RuijieOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class RuijieOSTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuijieOSTelnet(RuijieOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ruijie/ruijie_os.html b/docs/netmiko/ruijie/ruijie_os.html
new file mode 100644
index 000000000..8d281c753
--- /dev/null
+++ b/docs/netmiko/ruijie/ruijie_os.html
@@ -0,0 +1,686 @@
+
+
+
+
+
+
+netmiko.ruijie.ruijie_os API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ruijie.ruijie_os
+
+
+Ruijie RGOS Support
+
+Source code
+"""Ruijie RGOS Support"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class RuijieOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ """Ruijie OS requires enable mode to set terminal width"""
+ self.enable()
+ self.set_terminal_width(command="terminal width 256", pattern="terminal")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class RuijieOSSSH(RuijieOSBase):
+
+ pass
+
+
+class RuijieOSTelnet(RuijieOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class RuijieOSBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuijieOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ """Ruijie OS requires enable mode to set terminal width"""
+ self.enable()
+ self.set_terminal_width(command="terminal width 256", pattern="terminal")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Save config: write"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ """Ruijie OS requires enable mode to set terminal width"""
+ self.enable()
+ self.set_terminal_width(command="terminal width 256", pattern="terminal")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class RuijieOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuijieOSSSH(RuijieOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class RuijieOSTelnet
+(*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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class RuijieOSTelnet(RuijieOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/scp_functions.html b/docs/netmiko/scp_functions.html
new file mode 100644
index 000000000..2287195d7
--- /dev/null
+++ b/docs/netmiko/scp_functions.html
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+netmiko.scp_functions API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.scp_functions
+
+
+Netmiko SCP operations.
+Supports file get and file put operations.
+SCP requires a separate SSH connection for a control channel.
+
+Source code
+"""
+Netmiko SCP operations.
+
+Supports file get and file put operations.
+
+SCP requires a separate SSH connection for a control channel.
+"""
+from typing import AnyStr, Optional, Callable, Any, Dict
+from typing import TYPE_CHECKING
+from netmiko.scp_handler import BaseFileTransfer
+from netmiko.ssh_dispatcher import FileTransfer
+from netmiko.cisco.cisco_ios import InLineTransfer
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
+
+def progress_bar(
+ filename: AnyStr, size: int, sent: int, peername: Optional[str] = None
+) -> None:
+ max_width = 50
+ if isinstance(filename, bytes):
+ filename_str = filename.decode()
+ else:
+ filename_str = filename
+ clear_screen = chr(27) + "[2J"
+ terminating_char = "|"
+
+ # Percentage done
+ percent_complete = sent / size
+ percent_str = f"{percent_complete*100:.2f}%"
+ hash_count = int(percent_complete * max_width)
+ progress = hash_count * ">"
+
+ if peername is None:
+ header_msg = f"Transferring file: {filename_str}\n"
+ else:
+ header_msg = f"Transferring file to {peername}: {filename_str}\n"
+
+ msg = f"{progress:<50}{terminating_char:1} ({percent_str})"
+ print(clear_screen)
+ print(header_msg)
+ print(msg)
+
+
+def verifyspace_and_transferfile(scp_transfer: BaseFileTransfer) -> None:
+ """Verify space and transfer file."""
+ if not scp_transfer.verify_space_available():
+ raise ValueError("Insufficient space available on remote device")
+ scp_transfer.transfer_file()
+
+
+def file_transfer(
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ disable_md5: bool = False,
+ inline_transfer: bool = False,
+ overwrite_file: bool = False,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ verify_file: Optional[bool] = None,
+) -> Dict[str, bool]:
+ """Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
+
+ inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
+
+ return {
+ 'file_exists': boolean,
+ 'file_transferred': boolean,
+ 'file_verified': boolean,
+ }
+ """
+ transferred_and_verified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": True,
+ }
+ transferred_and_notverified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": False,
+ }
+ nottransferred_but_verified = {
+ "file_exists": True,
+ "file_transferred": False,
+ "file_verified": True,
+ }
+
+ if "cisco_ios" in ssh_conn.device_type or "cisco_xe" in ssh_conn.device_type:
+ cisco_ios = True
+ else:
+ cisco_ios = False
+ if not cisco_ios and inline_transfer:
+ raise ValueError("Inline Transfer only supported for Cisco IOS/Cisco IOS-XE")
+
+ # Replace disable_md5 argument with verify_file argument across time
+ if verify_file is None:
+ verify_file = not disable_md5
+
+ scp_args = {
+ "ssh_conn": ssh_conn,
+ "source_file": source_file,
+ "dest_file": dest_file,
+ "direction": direction,
+ "socket_timeout": socket_timeout,
+ "progress": progress,
+ "progress4": progress4,
+ }
+ if file_system is not None:
+ scp_args["file_system"] = file_system
+
+ TransferClass: Callable[..., BaseFileTransfer]
+ if inline_transfer:
+ TransferClass = InLineTransfer
+ else:
+ TransferClass = FileTransfer
+
+ with TransferClass(**scp_args) as scp_transfer:
+ if scp_transfer.check_file_exists():
+ if overwrite_file:
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ else:
+ # File exists, you can overwrite it, MD5 is wrong (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError(
+ "MD5 failure between source and destination files"
+ )
+ else:
+ # File exists, you can overwrite it, but MD5 not allowed (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ return transferred_and_notverified
+ else:
+ # File exists, but you can't overwrite it.
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ msg = "File already exists and overwrite_file is disabled"
+ raise ValueError(msg)
+ else:
+ verifyspace_and_transferfile(scp_transfer)
+ # File doesn't exist
+ if verify_file:
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError("MD5 failure between source and destination files")
+ else:
+ return transferred_and_notverified
+
+
+
+
+
+
+
+
+def file_transfer(ssh_conn, source_file, dest_file, file_system=None, direction='put', disable_md5=False, inline_transfer=False, overwrite_file=False, socket_timeout=10.0, progress=None, progress4=None, verify_file=None)
+
+-
+
Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
+inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
+return {
+'file_exists': boolean,
+'file_transferred': boolean,
+'file_verified': boolean,
+}
+
+Source code
+def file_transfer(
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ disable_md5: bool = False,
+ inline_transfer: bool = False,
+ overwrite_file: bool = False,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ verify_file: Optional[bool] = None,
+) -> Dict[str, bool]:
+ """Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
+
+ inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
+
+ return {
+ 'file_exists': boolean,
+ 'file_transferred': boolean,
+ 'file_verified': boolean,
+ }
+ """
+ transferred_and_verified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": True,
+ }
+ transferred_and_notverified = {
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": False,
+ }
+ nottransferred_but_verified = {
+ "file_exists": True,
+ "file_transferred": False,
+ "file_verified": True,
+ }
+
+ if "cisco_ios" in ssh_conn.device_type or "cisco_xe" in ssh_conn.device_type:
+ cisco_ios = True
+ else:
+ cisco_ios = False
+ if not cisco_ios and inline_transfer:
+ raise ValueError("Inline Transfer only supported for Cisco IOS/Cisco IOS-XE")
+
+ # Replace disable_md5 argument with verify_file argument across time
+ if verify_file is None:
+ verify_file = not disable_md5
+
+ scp_args = {
+ "ssh_conn": ssh_conn,
+ "source_file": source_file,
+ "dest_file": dest_file,
+ "direction": direction,
+ "socket_timeout": socket_timeout,
+ "progress": progress,
+ "progress4": progress4,
+ }
+ if file_system is not None:
+ scp_args["file_system"] = file_system
+
+ TransferClass: Callable[..., BaseFileTransfer]
+ if inline_transfer:
+ TransferClass = InLineTransfer
+ else:
+ TransferClass = FileTransfer
+
+ with TransferClass(**scp_args) as scp_transfer:
+ if scp_transfer.check_file_exists():
+ if overwrite_file:
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ else:
+ # File exists, you can overwrite it, MD5 is wrong (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError(
+ "MD5 failure between source and destination files"
+ )
+ else:
+ # File exists, you can overwrite it, but MD5 not allowed (transfer file)
+ verifyspace_and_transferfile(scp_transfer)
+ return transferred_and_notverified
+ else:
+ # File exists, but you can't overwrite it.
+ if verify_file:
+ if scp_transfer.verify_file():
+ return nottransferred_but_verified
+ msg = "File already exists and overwrite_file is disabled"
+ raise ValueError(msg)
+ else:
+ verifyspace_and_transferfile(scp_transfer)
+ # File doesn't exist
+ if verify_file:
+ if scp_transfer.verify_file():
+ return transferred_and_verified
+ else:
+ raise ValueError("MD5 failure between source and destination files")
+ else:
+ return transferred_and_notverified
+
+
+
+def progress_bar(filename, size, sent, peername=None)
+
+-
+
+
+Source code
+def progress_bar(
+ filename: AnyStr, size: int, sent: int, peername: Optional[str] = None
+) -> None:
+ max_width = 50
+ if isinstance(filename, bytes):
+ filename_str = filename.decode()
+ else:
+ filename_str = filename
+ clear_screen = chr(27) + "[2J"
+ terminating_char = "|"
+
+ # Percentage done
+ percent_complete = sent / size
+ percent_str = f"{percent_complete*100:.2f}%"
+ hash_count = int(percent_complete * max_width)
+ progress = hash_count * ">"
+
+ if peername is None:
+ header_msg = f"Transferring file: {filename_str}\n"
+ else:
+ header_msg = f"Transferring file to {peername}: {filename_str}\n"
+
+ msg = f"{progress:<50}{terminating_char:1} ({percent_str})"
+ print(clear_screen)
+ print(header_msg)
+ print(msg)
+
+
+
+def verifyspace_and_transferfile(scp_transfer)
+
+-
+
Verify space and transfer file.
+
+Source code
+def verifyspace_and_transferfile(scp_transfer: BaseFileTransfer) -> None:
+ """Verify space and transfer file."""
+ if not scp_transfer.verify_space_available():
+ raise ValueError("Insufficient space available on remote device")
+ scp_transfer.transfer_file()
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/scp_handler.html b/docs/netmiko/scp_handler.html
new file mode 100644
index 000000000..83dd64efd
--- /dev/null
+++ b/docs/netmiko/scp_handler.html
@@ -0,0 +1,1405 @@
+
+
+
+
+
+
+netmiko.scp_handler API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.scp_handler
+
+
+Netmiko SCP operations.
+Supports file get and file put operations.
+SCP requires a separate SSH connection for a control channel.
+
+Source code
+"""
+Netmiko SCP operations.
+
+Supports file get and file put operations.
+
+SCP requires a separate SSH connection for a control channel.
+"""
+from typing import Callable, Optional, Any, Type
+from typing import TYPE_CHECKING
+from types import TracebackType
+import re
+import os
+import hashlib
+
+import scp
+import sys
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
+
+class SCPConn(object):
+ """
+ Establish a secure copy channel to the remote network device.
+
+ Must close the SCP connection to get the file to write to the remote filesystem
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+ self.establish_scp_conn()
+
+ def establish_scp_conn(self) -> None:
+ """Establish the secure copy connection."""
+ ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
+ self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
+ self.scp_conn.connect(**ssh_connect_params)
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+ def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP (for backwards compatibility)."""
+ self.scp_client.put(source_file, dest_file)
+
+ def scp_get_file(self, source_file: str, dest_file: str) -> None:
+ """Get file using SCP."""
+ self.scp_client.get(source_file, dest_file)
+
+ def scp_put_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP."""
+ self.scp_client.put(source_file, dest_file)
+
+ def close(self) -> None:
+ """Close the SCP connection."""
+ self.scp_conn.close()
+
+
+class BaseFileTransfer(object):
+ """Class to manage SCP file transfer and associated SSH control channel."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ self.dest_file = dest_file
+ self.direction = direction
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ auto_flag = (
+ "cisco_ios" in ssh_conn.device_type
+ or "cisco_xe" in ssh_conn.device_type
+ or "cisco_xr" in ssh_conn.device_type
+ )
+ if not file_system:
+ if auto_flag:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ raise ValueError("Destination file system not specified")
+ else:
+ self.file_system = file_system
+
+ if direction == "put":
+ self.source_md5 = self.file_md5(source_file) if hash_supported else None
+ self.file_size = os.stat(source_file).st_size
+ elif direction == "get":
+ self.source_md5 = (
+ self.remote_md5(remote_file=source_file) if hash_supported else None
+ )
+ self.file_size = self.remote_file_size(remote_file=source_file)
+ else:
+ raise ValueError("Invalid direction specified")
+
+ def __enter__(self) -> "BaseFileTransfer":
+ """Context manager setup"""
+ self.establish_scp_conn()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ """Context manager cleanup."""
+ self.close_scp_chan()
+
+ def establish_scp_conn(self) -> None:
+ """Establish SCP connection."""
+ self.scp_conn = SCPConn(
+ self.ssh_ctl_chan,
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+ def close_scp_chan(self) -> None:
+ """Close the SCP connection to the remote network device."""
+ self.scp_conn.close()
+ del self.scp_conn
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"dir {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ if match:
+ if "kbytes" in match.group(0) or "Kbytes" in match.group(0):
+ return int(match.group(1)) * 1000
+ return int(match.group(1))
+ else:
+ msg = (
+ f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ )
+ raise ValueError(msg)
+
+ def _remote_space_available_unix(self, search_pattern: str = "") -> int:
+ """Return space available on *nix system (BSD/Linux)."""
+ self.ssh_ctl_chan._enter_shell()
+ remote_cmd = f"/bin/df -k {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+
+ # Try to ensure parsing is correct:
+ # Filesystem 1K-blocks Used Avail Capacity Mounted on
+ # /dev/bo0s3f 1264808 16376 1147248 1% /cf/var
+ remote_output = remote_output.strip()
+ output_lines = remote_output.splitlines()
+
+ # First line is the header; second is the actual file system info
+ header_line = output_lines[0]
+ filesystem_line = output_lines[1]
+
+ if "Filesystem" not in header_line or "Avail" not in header_line.split()[3]:
+ # Filesystem 1K-blocks Used Avail Capacity Mounted on
+ msg = "Parsing error, unexpected output from {}:\n{}".format(
+ remote_cmd, remote_output
+ )
+ raise ValueError(msg)
+
+ space_available = filesystem_line.split()[3]
+ if not re.search(r"^\d+$", space_available):
+ msg = "Parsing error, unexpected output from {}:\n{}".format(
+ remote_cmd, remote_output
+ )
+ raise ValueError(msg)
+
+ self.ssh_ctl_chan._return_cli()
+ return int(space_available) * 1024
+
+ def local_space_available(self) -> int:
+ """Return space available on local filesystem."""
+ if sys.platform == "win32":
+ import ctypes
+
+ free_bytes = ctypes.c_ulonglong(0)
+ ctypes.windll.kernel32.GetDiskFreeSpaceExW(
+ ctypes.c_wchar_p("."), None, None, ctypes.pointer(free_bytes)
+ )
+ return free_bytes.value
+ else:
+ destination_stats = os.statvfs(".")
+ return destination_stats.f_bsize * destination_stats.f_bavail
+
+ def verify_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ if self.direction == "put":
+ space_avail = self.remote_space_available(search_pattern=search_pattern)
+ elif self.direction == "get":
+ space_avail = self.local_space_available()
+ if space_avail > self.file_size:
+ return True
+ return False
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory of .*{0}".format(self.dest_file)
+ if (
+ "Error opening" in remote_out
+ or "No such file or directory" in remote_out
+ or "Path does not exist" in remote_out
+ ):
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def _check_file_exists_unix(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ self.ssh_ctl_chan._enter_shell()
+ remote_cmd = f"/bin/ls {self.file_system}"
+ remote_out = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ return self.dest_file in remote_out
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"dir {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ # Strip out "Directory of flash:/filename line
+ remote_out_lines = re.split(r"Directory of .*", remote_out)
+ remote_out = "".join(remote_out_lines)
+ # Match line containing file name
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ 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:
+ return int(file_size)
+
+ def _remote_file_size_unix(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ remote_file = f"{self.file_system}/{remote_file}"
+ if not remote_cmd:
+ remote_cmd = f"/bin/ls -l {remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ remote_out = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+ self.ssh_ctl_chan._return_cli()
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file.
+
+ add_newline is needed to support Cisco IOS MD5 calculation which expects the newline in
+ the string
+
+ Args:
+ file_name: name of file to get md5 digest of
+ add_newline: add newline to end of file contents or not
+
+ """
+ file_hash = hashlib.md5()
+ with open(file_name, "rb") as f:
+ while True:
+ file_contents = f.read(512)
+ if not file_contents:
+ if add_newline:
+ file_contents + b"\n"
+ break
+ file_hash.update(file_contents)
+ return file_hash.hexdigest()
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"=\s+(\S+)") -> str:
+ """
+ Process the string to retrieve the MD5 hash
+
+ Output from Cisco IOS (ASA is similar)
+ .MD5 of flash:file_name Done!
+ verify /md5 (flash:file_name) = 410db2a7015eaa42b1fe71f1bf3d59a2
+ """
+ match = re.search(pattern, md5_output)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+ def compare_md5(self) -> bool:
+ """Compare md5 of file on network device to md5 of local file."""
+ if self.direction == "put":
+ remote_md5 = self.remote_md5()
+ return self.source_md5 == remote_md5
+ elif self.direction == "get":
+ local_md5 = self.file_md5(self.dest_file)
+ return self.source_md5 == local_md5
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def transfer_file(self) -> None:
+ """SCP transfer file."""
+ if self.direction == "put":
+ self.put_file()
+ elif self.direction == "get":
+ self.get_file()
+ else:
+ raise ValueError("Unexpected value for self.direction in transfer_file")
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.file_system}/{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.file_system}/{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def verify_file(self) -> bool:
+ """Verify the file has been transferred correctly."""
+ return self.compare_md5()
+
+ def enable_scp(self, cmd: str = "ip scp server enable") -> None:
+ """
+ Enable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+ def disable_scp(self, cmd: str = "no ip scp server enable") -> None:
+ """
+ Disable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+
+
+
+
+
+
+
+
+class BaseFileTransfer
+(ssh_conn, source_file, dest_file, file_system=None, direction='put', socket_timeout=10.0, progress=None, progress4=None, hash_supported=True)
+
+-
+
Class to manage SCP file transfer and associated SSH control channel.
+
+Source code
+class BaseFileTransfer(object):
+ """Class to manage SCP file transfer and associated SSH control channel."""
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
+ self.dest_file = dest_file
+ self.direction = direction
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ auto_flag = (
+ "cisco_ios" in ssh_conn.device_type
+ or "cisco_xe" in ssh_conn.device_type
+ or "cisco_xr" in ssh_conn.device_type
+ )
+ if not file_system:
+ if auto_flag:
+ self.file_system = self.ssh_ctl_chan._autodetect_fs()
+ else:
+ raise ValueError("Destination file system not specified")
+ else:
+ self.file_system = file_system
+
+ if direction == "put":
+ self.source_md5 = self.file_md5(source_file) if hash_supported else None
+ self.file_size = os.stat(source_file).st_size
+ elif direction == "get":
+ self.source_md5 = (
+ self.remote_md5(remote_file=source_file) if hash_supported else None
+ )
+ self.file_size = self.remote_file_size(remote_file=source_file)
+ else:
+ raise ValueError("Invalid direction specified")
+
+ def __enter__(self) -> "BaseFileTransfer":
+ """Context manager setup"""
+ self.establish_scp_conn()
+ return self
+
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ """Context manager cleanup."""
+ self.close_scp_chan()
+
+ def establish_scp_conn(self) -> None:
+ """Establish SCP connection."""
+ self.scp_conn = SCPConn(
+ self.ssh_ctl_chan,
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+ def close_scp_chan(self) -> None:
+ """Close the SCP connection to the remote network device."""
+ self.scp_conn.close()
+ del self.scp_conn
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"dir {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ if match:
+ if "kbytes" in match.group(0) or "Kbytes" in match.group(0):
+ return int(match.group(1)) * 1000
+ return int(match.group(1))
+ else:
+ msg = (
+ f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ )
+ raise ValueError(msg)
+
+ def _remote_space_available_unix(self, search_pattern: str = "") -> int:
+ """Return space available on *nix system (BSD/Linux)."""
+ self.ssh_ctl_chan._enter_shell()
+ remote_cmd = f"/bin/df -k {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+
+ # Try to ensure parsing is correct:
+ # Filesystem 1K-blocks Used Avail Capacity Mounted on
+ # /dev/bo0s3f 1264808 16376 1147248 1% /cf/var
+ remote_output = remote_output.strip()
+ output_lines = remote_output.splitlines()
+
+ # First line is the header; second is the actual file system info
+ header_line = output_lines[0]
+ filesystem_line = output_lines[1]
+
+ if "Filesystem" not in header_line or "Avail" not in header_line.split()[3]:
+ # Filesystem 1K-blocks Used Avail Capacity Mounted on
+ msg = "Parsing error, unexpected output from {}:\n{}".format(
+ remote_cmd, remote_output
+ )
+ raise ValueError(msg)
+
+ space_available = filesystem_line.split()[3]
+ if not re.search(r"^\d+$", space_available):
+ msg = "Parsing error, unexpected output from {}:\n{}".format(
+ remote_cmd, remote_output
+ )
+ raise ValueError(msg)
+
+ self.ssh_ctl_chan._return_cli()
+ return int(space_available) * 1024
+
+ def local_space_available(self) -> int:
+ """Return space available on local filesystem."""
+ if sys.platform == "win32":
+ import ctypes
+
+ free_bytes = ctypes.c_ulonglong(0)
+ ctypes.windll.kernel32.GetDiskFreeSpaceExW(
+ ctypes.c_wchar_p("."), None, None, ctypes.pointer(free_bytes)
+ )
+ return free_bytes.value
+ else:
+ destination_stats = os.statvfs(".")
+ return destination_stats.f_bsize * destination_stats.f_bavail
+
+ def verify_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ if self.direction == "put":
+ space_avail = self.remote_space_available(search_pattern=search_pattern)
+ elif self.direction == "get":
+ space_avail = self.local_space_available()
+ if space_avail > self.file_size:
+ return True
+ return False
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory of .*{0}".format(self.dest_file)
+ if (
+ "Error opening" in remote_out
+ or "No such file or directory" in remote_out
+ or "Path does not exist" in remote_out
+ ):
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def _check_file_exists_unix(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ self.ssh_ctl_chan._enter_shell()
+ remote_cmd = f"/bin/ls {self.file_system}"
+ remote_out = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ return self.dest_file in remote_out
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"dir {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ # Strip out "Directory of flash:/filename line
+ remote_out_lines = re.split(r"Directory of .*", remote_out)
+ remote_out = "".join(remote_out_lines)
+ # Match line containing file name
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ 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:
+ return int(file_size)
+
+ def _remote_file_size_unix(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ remote_file = f"{self.file_system}/{remote_file}"
+ if not remote_cmd:
+ remote_cmd = f"/bin/ls -l {remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ remote_out = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
+ self.ssh_ctl_chan._return_cli()
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file.
+
+ add_newline is needed to support Cisco IOS MD5 calculation which expects the newline in
+ the string
+
+ Args:
+ file_name: name of file to get md5 digest of
+ add_newline: add newline to end of file contents or not
+
+ """
+ file_hash = hashlib.md5()
+ with open(file_name, "rb") as f:
+ while True:
+ file_contents = f.read(512)
+ if not file_contents:
+ if add_newline:
+ file_contents + b"\n"
+ break
+ file_hash.update(file_contents)
+ return file_hash.hexdigest()
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"=\s+(\S+)") -> str:
+ """
+ Process the string to retrieve the MD5 hash
+
+ Output from Cisco IOS (ASA is similar)
+ .MD5 of flash:file_name Done!
+ verify /md5 (flash:file_name) = 410db2a7015eaa42b1fe71f1bf3d59a2
+ """
+ match = re.search(pattern, md5_output)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+ def compare_md5(self) -> bool:
+ """Compare md5 of file on network device to md5 of local file."""
+ if self.direction == "put":
+ remote_md5 = self.remote_md5()
+ return self.source_md5 == remote_md5
+ elif self.direction == "get":
+ local_md5 = self.file_md5(self.dest_file)
+ return self.source_md5 == local_md5
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+ def transfer_file(self) -> None:
+ """SCP transfer file."""
+ if self.direction == "put":
+ self.put_file()
+ elif self.direction == "get":
+ self.get_file()
+ else:
+ raise ValueError("Unexpected value for self.direction in transfer_file")
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.file_system}/{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.file_system}/{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def verify_file(self) -> bool:
+ """Verify the file has been transferred correctly."""
+ return self.compare_md5()
+
+ def enable_scp(self, cmd: str = "ip scp server enable") -> None:
+ """
+ Enable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+ def disable_scp(self, cmd: str = "no ip scp server enable") -> None:
+ """
+ Disable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+Subclasses
+
+Static methods
+
+
+def process_md5(md5_output, pattern='=\\s+(\\S+)')
+
+-
+
Process the string to retrieve the MD5 hash
+Output from Cisco IOS (ASA is similar)
+.MD5 of flash:file_name Done!
+verify /md5 (flash:file_name) = 410db2a7015eaa42b1fe71f1bf3d59a2
+
+Source code
+@staticmethod
+def process_md5(md5_output: str, pattern: str = r"=\s+(\S+)") -> str:
+ """
+ Process the string to retrieve the MD5 hash
+
+ Output from Cisco IOS (ASA is similar)
+ .MD5 of flash:file_name Done!
+ verify /md5 (flash:file_name) = 410db2a7015eaa42b1fe71f1bf3d59a2
+ """
+ match = re.search(pattern, md5_output)
+ if match:
+ return match.group(1)
+ else:
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
+
+
+
+Methods
+
+
+def check_file_exists(self, remote_cmd='')
+
+-
+
Check if the dest_file already exists on the file system (return boolean).
+
+Source code
+def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"dir {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory of .*{0}".format(self.dest_file)
+ if (
+ "Error opening" in remote_out
+ or "No such file or directory" in remote_out
+ or "Path does not exist" in remote_out
+ ):
+ return False
+ elif re.search(search_string, remote_out, flags=re.DOTALL):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+
+
+def close_scp_chan(self)
+
+-
+
Close the SCP connection to the remote network device.
+
+Source code
+def close_scp_chan(self) -> None:
+ """Close the SCP connection to the remote network device."""
+ self.scp_conn.close()
+ del self.scp_conn
+
+
+
+def compare_md5(self)
+
+-
+
Compare md5 of file on network device to md5 of local file.
+
+Source code
+def compare_md5(self) -> bool:
+ """Compare md5 of file on network device to md5 of local file."""
+ if self.direction == "put":
+ remote_md5 = self.remote_md5()
+ return self.source_md5 == remote_md5
+ elif self.direction == "get":
+ local_md5 = self.file_md5(self.dest_file)
+ return self.source_md5 == local_md5
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+
+
+def disable_scp(self, cmd='no ip scp server enable')
+
+-
+
Disable SCP on remote device.
+Defaults to Cisco IOS command
+
+Source code
+def disable_scp(self, cmd: str = "no ip scp server enable") -> None:
+ """
+ Disable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+
+
+def enable_scp(self, cmd='ip scp server enable')
+
+-
+
Enable SCP on remote device.
+Defaults to Cisco IOS command
+
+Source code
+def enable_scp(self, cmd: str = "ip scp server enable") -> None:
+ """
+ Enable SCP on remote device.
+
+ Defaults to Cisco IOS command
+ """
+ self.ssh_ctl_chan.send_config_set(cmd)
+
+
+
+def establish_scp_conn(self)
+
+-
+
Establish SCP connection.
+
+Source code
+def establish_scp_conn(self) -> None:
+ """Establish SCP connection."""
+ self.scp_conn = SCPConn(
+ self.ssh_ctl_chan,
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+
+
+def file_md5(self, file_name, add_newline=False)
+
+-
+
Compute MD5 hash of file.
+add_newline is needed to support Cisco IOS MD5 calculation which expects the newline in
+the string
+Args
+
+file_name
+- name of file to get md5 digest of
+add_newline
+- add newline to end of file contents or not
+
+
+Source code
+def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file.
+
+ add_newline is needed to support Cisco IOS MD5 calculation which expects the newline in
+ the string
+
+ Args:
+ file_name: name of file to get md5 digest of
+ add_newline: add newline to end of file contents or not
+
+ """
+ file_hash = hashlib.md5()
+ with open(file_name, "rb") as f:
+ while True:
+ file_contents = f.read(512)
+ if not file_contents:
+ if add_newline:
+ file_contents + b"\n"
+ break
+ file_hash.update(file_contents)
+ return file_hash.hexdigest()
+
+
+
+def get_file(self)
+
+-
+
SCP copy the file from the remote device to local system.
+
+Source code
+def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.file_system}/{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
+
+
+
+def local_space_available(self)
+
+-
+
Return space available on local filesystem.
+
+Source code
+def local_space_available(self) -> int:
+ """Return space available on local filesystem."""
+ if sys.platform == "win32":
+ import ctypes
+
+ free_bytes = ctypes.c_ulonglong(0)
+ ctypes.windll.kernel32.GetDiskFreeSpaceExW(
+ ctypes.c_wchar_p("."), None, None, ctypes.pointer(free_bytes)
+ )
+ return free_bytes.value
+ else:
+ destination_stats = os.statvfs(".")
+ return destination_stats.f_bsize * destination_stats.f_bavail
+
+
+
+def put_file(self)
+
+-
+
SCP copy the file from the local system to the remote device.
+
+Source code
+def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.file_system}/{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+
+
+def remote_file_size(self, remote_cmd='', remote_file=None)
+
+-
+
Get the file size of the remote file.
+
+Source code
+def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+) -> int:
+ """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 = f"dir {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ # Strip out "Directory of flash:/filename line
+ remote_out_lines = re.split(r"Directory of .*", remote_out)
+ remote_out = "".join(remote_out_lines)
+ # Match line containing file name
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ 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:
+ return int(file_size)
+
+
+
+def remote_md5(self, base_cmd='verify /md5', remote_file=None)
+
+-
+
Calculate remote MD5 and returns the hash.
+This command can be CPU intensive on the remote device.
+
+Source code
+def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5
+
+
+
+def remote_space_available(self, search_pattern='(\\d+) \\w+ free')
+
+-
+
Return space available on remote device.
+
+Source code
+def remote_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"dir {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ if match:
+ if "kbytes" in match.group(0) or "Kbytes" in match.group(0):
+ return int(match.group(1)) * 1000
+ return int(match.group(1))
+ else:
+ msg = (
+ f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ )
+ raise ValueError(msg)
+
+
+
+def transfer_file(self)
+
+-
+
+
+Source code
+def transfer_file(self) -> None:
+ """SCP transfer file."""
+ if self.direction == "put":
+ self.put_file()
+ elif self.direction == "get":
+ self.get_file()
+ else:
+ raise ValueError("Unexpected value for self.direction in transfer_file")
+
+
+
+def verify_file(self)
+
+-
+
Verify the file has been transferred correctly.
+
+Source code
+def verify_file(self) -> bool:
+ """Verify the file has been transferred correctly."""
+ return self.compare_md5()
+
+
+
+def verify_space_available(self, search_pattern='(\\d+) \\w+ free')
+
+-
+
Verify sufficient space is available on destination file system (return boolean).
+
+Source code
+def verify_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ if self.direction == "put":
+ space_avail = self.remote_space_available(search_pattern=search_pattern)
+ elif self.direction == "get":
+ space_avail = self.local_space_available()
+ if space_avail > self.file_size:
+ return True
+ return False
+
+
+
+
+
+class SCPConn
+(ssh_conn, socket_timeout=10.0, progress=None, progress4=None)
+
+-
+
Establish a secure copy channel to the remote network device.
+Must close the SCP connection to get the file to write to the remote filesystem
+
+Source code
+class SCPConn(object):
+ """
+ Establish a secure copy channel to the remote network device.
+
+ Must close the SCP connection to get the file to write to the remote filesystem
+ """
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ ) -> None:
+ self.ssh_ctl_chan = ssh_conn
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+ self.establish_scp_conn()
+
+ def establish_scp_conn(self) -> None:
+ """Establish the secure copy connection."""
+ ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
+ self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
+ self.scp_conn.connect(**ssh_connect_params)
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+ def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP (for backwards compatibility)."""
+ self.scp_client.put(source_file, dest_file)
+
+ def scp_get_file(self, source_file: str, dest_file: str) -> None:
+ """Get file using SCP."""
+ self.scp_client.get(source_file, dest_file)
+
+ def scp_put_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP."""
+ self.scp_client.put(source_file, dest_file)
+
+ def close(self) -> None:
+ """Close the SCP connection."""
+ self.scp_conn.close()
+
+Methods
+
+
+def close(self)
+
+-
+
Close the SCP connection.
+
+Source code
+def close(self) -> None:
+ """Close the SCP connection."""
+ self.scp_conn.close()
+
+
+
+def establish_scp_conn(self)
+
+-
+
Establish the secure copy connection.
+
+Source code
+def establish_scp_conn(self) -> None:
+ """Establish the secure copy connection."""
+ ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
+ self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
+ self.scp_conn.connect(**ssh_connect_params)
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
+
+
+
+def scp_get_file(self, source_file, dest_file)
+
+-
+
+
+Source code
+def scp_get_file(self, source_file: str, dest_file: str) -> None:
+ """Get file using SCP."""
+ self.scp_client.get(source_file, dest_file)
+
+
+
+def scp_put_file(self, source_file, dest_file)
+
+-
+
+
+Source code
+def scp_put_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP."""
+ self.scp_client.put(source_file, dest_file)
+
+
+
+def scp_transfer_file(self, source_file, dest_file)
+
+-
+
Put file using SCP (for backwards compatibility).
+
+Source code
+def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
+ """Put file using SCP (for backwards compatibility)."""
+ self.scp_client.put(source_file, dest_file)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/session_log.html b/docs/netmiko/session_log.html
new file mode 100644
index 000000000..419f0ca7f
--- /dev/null
+++ b/docs/netmiko/session_log.html
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+netmiko.session_log API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.session_log
+
+
+
+Source code
+import io
+from netmiko.utilities import write_bytes
+from typing import Dict, Any, Union, Optional, TextIO
+
+
+class SessionLog:
+ def __init__(
+ self,
+ file_name: Optional[str] = None,
+ buffered_io: Optional[io.BufferedIOBase] = None,
+ file_mode: str = "write",
+ file_encoding: str = "utf-8",
+ no_log: Dict[str, Any] = None,
+ record_writes: bool = False,
+ ) -> None:
+ if no_log is None:
+ self.no_log = {}
+ else:
+ self.no_log = no_log
+ self.file_name = file_name
+ self.file_mode = file_mode
+ self.file_encoding = file_encoding
+ self.record_writes = record_writes
+ self._session_log_close = False
+
+ # Actual file/file-handle/buffered-IO that will be written to.
+ self.session_log: Union[io.BufferedIOBase, TextIO, None]
+ if file_name is None and buffered_io:
+ self.session_log = buffered_io
+ else:
+ self.session_log = None
+
+ # Ensures last write operations prior to disconnect are recorded.
+ self.fin = False
+
+ def open(self) -> None:
+ """Open the session_log file."""
+ if self.file_name is None:
+ return None
+ if self.file_mode == "append":
+ self.session_log = open(
+ self.file_name, mode="a", encoding=self.file_encoding
+ )
+ else:
+ self.session_log = open(
+ self.file_name, mode="w", encoding=self.file_encoding
+ )
+ self._session_log_close = True
+
+ def close(self) -> None:
+ """Close the session_log file (if it is a file that we opened)."""
+ if self.session_log and self._session_log_close:
+ self.session_log.close()
+ self.session_log = None
+
+ def write(self, data: str) -> None:
+ if self.session_log is not None and len(data) > 0:
+ # Hide the password and secret in the session_log
+ for hidden_data in self.no_log.values():
+ data = data.replace(hidden_data, "********")
+
+ if isinstance(self.session_log, io.BufferedIOBase):
+ self.session_log.write(write_bytes(data, encoding=self.file_encoding))
+ else:
+ self.session_log.write(data)
+
+ assert isinstance(self.session_log, io.BufferedIOBase) or isinstance(
+ self.session_log, io.TextIOBase
+ )
+ self.session_log.flush()
+
+
+
+
+
+
+
+
+
+class SessionLog
+(file_name=None, buffered_io=None, file_mode='write', file_encoding='utf-8', no_log=None, record_writes=False)
+
+-
+
+
+Source code
+class SessionLog:
+ def __init__(
+ self,
+ file_name: Optional[str] = None,
+ buffered_io: Optional[io.BufferedIOBase] = None,
+ file_mode: str = "write",
+ file_encoding: str = "utf-8",
+ no_log: Dict[str, Any] = None,
+ record_writes: bool = False,
+ ) -> None:
+ if no_log is None:
+ self.no_log = {}
+ else:
+ self.no_log = no_log
+ self.file_name = file_name
+ self.file_mode = file_mode
+ self.file_encoding = file_encoding
+ self.record_writes = record_writes
+ self._session_log_close = False
+
+ # Actual file/file-handle/buffered-IO that will be written to.
+ self.session_log: Union[io.BufferedIOBase, TextIO, None]
+ if file_name is None and buffered_io:
+ self.session_log = buffered_io
+ else:
+ self.session_log = None
+
+ # Ensures last write operations prior to disconnect are recorded.
+ self.fin = False
+
+ def open(self) -> None:
+ """Open the session_log file."""
+ if self.file_name is None:
+ return None
+ if self.file_mode == "append":
+ self.session_log = open(
+ self.file_name, mode="a", encoding=self.file_encoding
+ )
+ else:
+ self.session_log = open(
+ self.file_name, mode="w", encoding=self.file_encoding
+ )
+ self._session_log_close = True
+
+ def close(self) -> None:
+ """Close the session_log file (if it is a file that we opened)."""
+ if self.session_log and self._session_log_close:
+ self.session_log.close()
+ self.session_log = None
+
+ def write(self, data: str) -> None:
+ if self.session_log is not None and len(data) > 0:
+ # Hide the password and secret in the session_log
+ for hidden_data in self.no_log.values():
+ data = data.replace(hidden_data, "********")
+
+ if isinstance(self.session_log, io.BufferedIOBase):
+ self.session_log.write(write_bytes(data, encoding=self.file_encoding))
+ else:
+ self.session_log.write(data)
+
+ assert isinstance(self.session_log, io.BufferedIOBase) or isinstance(
+ self.session_log, io.TextIOBase
+ )
+ self.session_log.flush()
+
+Methods
+
+
+def close(self)
+
+-
+
Close the session_log file (if it is a file that we opened).
+
+Source code
+def close(self) -> None:
+ """Close the session_log file (if it is a file that we opened)."""
+ if self.session_log and self._session_log_close:
+ self.session_log.close()
+ self.session_log = None
+
+
+
+def open(self)
+
+-
+
Open the session_log file.
+
+Source code
+def open(self) -> None:
+ """Open the session_log file."""
+ if self.file_name is None:
+ return None
+ if self.file_mode == "append":
+ self.session_log = open(
+ self.file_name, mode="a", encoding=self.file_encoding
+ )
+ else:
+ self.session_log = open(
+ self.file_name, mode="w", encoding=self.file_encoding
+ )
+ self._session_log_close = True
+
+
+
+def write(self, data)
+
+-
+
+
+Source code
+def write(self, data: str) -> None:
+ if self.session_log is not None and len(data) > 0:
+ # Hide the password and secret in the session_log
+ for hidden_data in self.no_log.values():
+ data = data.replace(hidden_data, "********")
+
+ if isinstance(self.session_log, io.BufferedIOBase):
+ self.session_log.write(write_bytes(data, encoding=self.file_encoding))
+ else:
+ self.session_log.write(data)
+
+ assert isinstance(self.session_log, io.BufferedIOBase) or isinstance(
+ self.session_log, io.TextIOBase
+ )
+ self.session_log.flush()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/sixwind/index.html b/docs/netmiko/sixwind/index.html
new file mode 100644
index 000000000..68802591d
--- /dev/null
+++ b/docs/netmiko/sixwind/index.html
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+netmiko.sixwind API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.sixwind
+
+
+
+Source code
+from netmiko.sixwind.sixwind_os import SixwindOSSSH
+
+__all__ = ["SixwindOSSSH"]
+
+
+
+
+
+
+
+
+
+class SixwindOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SixwindOSSSH(SixwindOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/sixwind/sixwind_os.html b/docs/netmiko/sixwind/sixwind_os.html
new file mode 100644
index 000000000..71fbc3476
--- /dev/null
+++ b/docs/netmiko/sixwind/sixwind_os.html
@@ -0,0 +1,785 @@
+
+
+
+
+
+
+netmiko.sixwind.sixwind_os API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.sixwind.sixwind_os
+
+
+
+Source code
+from typing import Optional, Any
+import time
+import warnings
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class SixwindOSBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """6WIND requires no-pager at the end of command, not implemented at this time."""
+ pass
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def config_mode(
+ self, config_command: str = "edit running", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Raise an error and return the failure if the commit fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"#",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "copy running startup",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for 6WIND"""
+
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class SixwindOSSSH(SixwindOSBase):
+
+ pass
+
+
+
+
+
+
+
+
+
+class SixwindOSBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SixwindOSBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """6WIND requires no-pager at the end of command, not implemented at this time."""
+ pass
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def config_mode(
+ self, config_command: str = "edit running", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Raise an error and return the failure if the commit fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"#",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "copy running startup",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for 6WIND"""
+
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Checks whether in configuration mode. Returns a boolean.
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
Commit the candidate configuration.
+Raise an error and return the failure if the commit fails.
+delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ Commit the candidate configuration.
+
+ Raise an error and return the failure if the commit fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"#",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+
+ return output
+
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
6WIND requires no-pager at the end of command, not implemented at this time.
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """6WIND requires no-pager at the end of command, not implemented at this time."""
+ pass
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='>')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def save_config(self, cmd='copy running startup', confirm=True, confirm_response='y')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running startup",
+ confirm: bool = True,
+ confirm_response: str = "y",
+) -> str:
+ """Save Config for 6WIND"""
+
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+class SixwindOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SixwindOSSSH(SixwindOSBase):
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/snmp_autodetect.html b/docs/netmiko/snmp_autodetect.html
new file mode 100644
index 000000000..819d62b05
--- /dev/null
+++ b/docs/netmiko/snmp_autodetect.html
@@ -0,0 +1,777 @@
+
+
+
+
+
+
+netmiko.snmp_autodetect API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.snmp_autodetect
+
+
+This module is used to auto-detect the type of a device in order to automatically create a
+Netmiko connection.
+The will avoid to hard coding the 'device_type' when using the ConnectHandler factory function
+from Netmiko.
+Example:
+from netmiko.snmp_autodetect import SNMPDetect
+my_snmp = SNMPDetect(hostname='1.1.1.70', user='pysnmp', auth_key='key1', encrypt_key='key2')
+device_type = my_snmp.autodetect()
+
+autodetect will return None if no match.
+SNMPDetect class defaults to SNMPv3
+Note, pysnmp is a required dependency for SNMPDetect and is intentionally not included in
+netmiko requirements. So installation of pysnmp might be required.
+
+Source code
+"""
+This module is used to auto-detect the type of a device in order to automatically create a
+Netmiko connection.
+
+The will avoid to hard coding the 'device_type' when using the ConnectHandler factory function
+from Netmiko.
+
+Example:
+------------------
+from netmiko.snmp_autodetect import SNMPDetect
+
+my_snmp = SNMPDetect(hostname='1.1.1.70', user='pysnmp', auth_key='key1', encrypt_key='key2')
+device_type = my_snmp.autodetect()
+------------------
+
+autodetect will return None if no match.
+
+SNMPDetect class defaults to SNMPv3
+
+Note, pysnmp is a required dependency for SNMPDetect and is intentionally not included in
+netmiko requirements. So installation of pysnmp might be required.
+"""
+from typing import Optional, Dict
+from typing.re import Pattern
+import re
+
+try:
+ from pysnmp.entity.rfc3413.oneliner import cmdgen
+except ImportError:
+ raise ImportError("pysnmp not installed; please install it: 'pip install pysnmp'")
+
+from netmiko.ssh_dispatcher import CLASS_MAPPER
+
+
+# Higher priority indicates a better match.
+SNMP_MAPPER_BASE = {
+ "arista_eos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Arista Networks EOS.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "paloalto_panos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Palo Alto Networks.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "hp_comware": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*HP(E)? Comware.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "hp_procurve": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".ProCurve", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_ios": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco IOS Software,.*", re.IGNORECASE),
+ "priority": 60,
+ },
+ "cisco_xe": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*IOS-XE Software,.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_xr": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco IOS XR Software.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_asa": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco Adaptive Security Appliance.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_nxos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco NX-OS.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_wlc": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco Controller.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "f5_tmsh": {
+ "oid": ".1.3.6.1.4.1.3375.2.1.4.1.0",
+ "expr": re.compile(r".*BIG-IP.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "fortinet": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r"Forti.*", re.IGNORECASE),
+ "priority": 80,
+ },
+ "checkpoint": {
+ "oid": ".1.3.6.1.4.1.2620.1.6.16.9.0",
+ "expr": re.compile(r"CheckPoint"),
+ "priority": 79,
+ },
+ "juniper_junos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Juniper.*"),
+ "priority": 99,
+ },
+ "nokia_sros": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*TiMOS.*"),
+ "priority": 99,
+ },
+ "dell_powerconnect": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r"PowerConnect.*", re.IGNORECASE),
+ "priority": 50,
+ },
+}
+
+# Ensure all SNMP device types are supported by Netmiko
+SNMP_MAPPER = {}
+std_device_types = list(CLASS_MAPPER.keys())
+for device_type in std_device_types:
+ if SNMP_MAPPER_BASE.get(device_type):
+ SNMP_MAPPER[device_type] = SNMP_MAPPER_BASE[device_type]
+
+
+class SNMPDetect(object):
+ """
+ The SNMPDetect class tries to automatically determine the device type.
+
+ Typically this will use the MIB-2 SysDescr and regular expressions.
+
+ Parameters
+ ----------
+ hostname: str
+ The name or IP address of the hostname we want to guess the type
+ snmp_version : str, optional ('v1', 'v2c' or 'v3')
+ The SNMP version that is running on the device (default: 'v3')
+ snmp_port : int, optional
+ The UDP port on which SNMP is listening (default: 161)
+ community : str, optional
+ The SNMP read community when using SNMPv2 (default: None)
+ user : str, optional
+ The SNMPv3 user for authentication (default: '')
+ auth_key : str, optional
+ The SNMPv3 authentication key (default: '')
+ encrypt_key : str, optional
+ The SNMPv3 encryption key (default: '')
+ auth_proto : str, optional ('des', '3des', 'aes128', 'aes192', 'aes256')
+ The SNMPv3 authentication protocol (default: 'aes128')
+ encrypt_proto : str, optional ('sha', 'md5')
+ The SNMPv3 encryption protocol (default: 'sha')
+
+ Attributes
+ ----------
+ hostname: str
+ The name or IP address of the device we want to guess the type
+ snmp_version : str
+ The SNMP version that is running on the device
+ snmp_port : int
+ The UDP port on which SNMP is listening
+ community : str
+ The SNMP read community when using SNMPv2
+ user : str
+ The SNMPv3 user for authentication
+ auth_key : str
+ The SNMPv3 authentication key
+ encrypt_key : str
+ The SNMPv3 encryption key
+ auth_proto : str
+ The SNMPv3 authentication protocol
+ encrypt_proto : str
+ The SNMPv3 encryption protocol
+
+ Methods
+ -------
+ autodetect()
+ Try to determine the device type.
+
+ """
+
+ def __init__(
+ self,
+ hostname: str,
+ snmp_version: str = "v3",
+ snmp_port: int = 161,
+ community: Optional[str] = None,
+ user: str = "",
+ auth_key: str = "",
+ encrypt_key: str = "",
+ auth_proto: str = "sha",
+ encrypt_proto: str = "aes128",
+ ) -> None:
+
+ # Check that the SNMP version is matching predefined type or raise ValueError
+ if snmp_version == "v1" or snmp_version == "v2c":
+ if not community:
+ raise ValueError("SNMP version v1/v2c community must be set.")
+ elif snmp_version == "v3":
+ if not user:
+ raise ValueError("SNMP version v3 user and password must be set")
+ else:
+ raise ValueError("SNMP version must be set to 'v1', 'v2c' or 'v3'")
+
+ # Check that the SNMPv3 auth & priv parameters match allowed types
+ self._snmp_v3_authentication = {
+ "sha": cmdgen.usmHMACSHAAuthProtocol,
+ "md5": cmdgen.usmHMACMD5AuthProtocol,
+ }
+ self._snmp_v3_encryption = {
+ "des": cmdgen.usmDESPrivProtocol,
+ "3des": cmdgen.usm3DESEDEPrivProtocol,
+ "aes128": cmdgen.usmAesCfb128Protocol,
+ "aes192": cmdgen.usmAesCfb192Protocol,
+ "aes256": cmdgen.usmAesCfb256Protocol,
+ }
+ if auth_proto not in self._snmp_v3_authentication.keys():
+ raise ValueError(
+ "SNMP V3 'auth_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_authentication.keys()
+ )
+ )
+ if encrypt_proto not in self._snmp_v3_encryption.keys():
+ raise ValueError(
+ "SNMP V3 'encrypt_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_encryption.keys()
+ )
+ )
+
+ self.hostname = hostname
+ self.snmp_version = snmp_version
+ self.snmp_port = snmp_port
+ self.community = community
+ self.user = user
+ self.auth_key = auth_key
+ self.encrypt_key = encrypt_key
+ self.auth_proto = self._snmp_v3_authentication[auth_proto]
+ self.encryp_proto = self._snmp_v3_encryption[encrypt_proto]
+ self._response_cache: Dict[str, str] = {}
+
+ def _get_snmpv3(self, oid: str) -> str:
+ """
+ Try to send an SNMP GET operation using SNMPv3 for the specified OID.
+
+ Parameters
+ ----------
+ oid : str
+ The SNMP OID that you want to get.
+
+ Returns
+ -------
+ string : str
+ The string as part of the value from the OID you are trying to retrieve.
+ """
+ snmp_target = (self.hostname, self.snmp_port)
+ cmd_gen = cmdgen.CommandGenerator()
+
+ (error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
+ cmdgen.UsmUserData(
+ self.user,
+ self.auth_key,
+ self.encrypt_key,
+ authProtocol=self.auth_proto,
+ privProtocol=self.encryp_proto,
+ ),
+ cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
+
+ if not error_detected and snmp_data[0][1]:
+ return str(snmp_data[0][1])
+ return ""
+
+ def _get_snmpv2c(self, oid: str) -> str:
+ """
+ Try to send an SNMP GET operation using SNMPv2 for the specified OID.
+
+ Parameters
+ ----------
+ oid : str
+ The SNMP OID that you want to get.
+
+ Returns
+ -------
+ string : str
+ The string as part of the value from the OID you are trying to retrieve.
+ """
+ snmp_target = (self.hostname, self.snmp_port)
+ cmd_gen = cmdgen.CommandGenerator()
+
+ (error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
+ cmdgen.CommunityData(self.community),
+ cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
+
+ if not error_detected and snmp_data[0][1]:
+ return str(snmp_data[0][1])
+ return ""
+
+ def _get_snmp(self, oid: str) -> str:
+ """Wrapper for generic SNMP call."""
+ if self.snmp_version in ["v1", "v2c"]:
+ return self._get_snmpv2c(oid)
+ else:
+ return self._get_snmpv3(oid)
+
+ def autodetect(self) -> Optional[str]:
+ """
+ Try to guess the device_type using SNMP GET based on the SNMP_MAPPER dict. The type which
+ is returned is directly matching the name in *netmiko.ssh_dispatcher.CLASS_MAPPER_BASE*
+ dict.
+
+ Thus you can use this name to retrieve automatically the right ConnectionClass
+
+ Returns
+ -------
+ potential_type : str
+ The name of the device_type that must be running.
+ """
+ # Convert SNMP_MAPPER to a list and sort by priority
+ snmp_mapper_orig = []
+ for k, v in SNMP_MAPPER.items():
+ snmp_mapper_orig.append({k: v})
+ snmp_mapper_list = sorted(
+ snmp_mapper_orig, key=lambda x: list(x.values())[0]["priority"] # type: ignore
+ )
+ snmp_mapper_list.reverse()
+
+ for entry in snmp_mapper_list:
+ for device_type, v in entry.items():
+ oid: str = v["oid"] # type: ignore
+ regex: Pattern = v["expr"]
+
+ # Used cache data if we already queryied this OID
+ if self._response_cache.get(oid):
+ snmp_response = self._response_cache.get(oid)
+ else:
+ snmp_response = self._get_snmp(oid)
+ self._response_cache[oid] = snmp_response
+
+ # See if we had a match
+ if re.search(regex, snmp_response):
+ assert isinstance(device_type, str)
+ return device_type
+
+ return None
+
+
+
+
+
+
+
+
+
+class SNMPDetect
+(hostname, snmp_version='v3', snmp_port=161, community=None, user='', auth_key='', encrypt_key='', auth_proto='sha', encrypt_proto='aes128')
+
+-
+
The SNMPDetect class tries to automatically determine the device type.
+Typically this will use the MIB-2 SysDescr and regular expressions.
+Parameters
+
+hostname : str
+- The name or IP address of the hostname we want to guess the type
+snmp_version : str, optional ('v1', 'v2c' or 'v3')
+- The SNMP version that is running on the device (default: 'v3')
+snmp_port : int, optional
+- The UDP port on which SNMP is listening (default: 161)
+community : str, optional
+- The SNMP read community when using SNMPv2 (default: None)
+user : str, optional
+- The SNMPv3 user for authentication (default: '')
+auth_key : str, optional
+- The SNMPv3 authentication key (default: '')
+encrypt_key : str, optional
+- The SNMPv3 encryption key (default: '')
+auth_proto : str, optional ('des', '3des', 'aes128', 'aes192', 'aes256')
+- The SNMPv3 authentication protocol (default: 'aes128')
+encrypt_proto : str, optional ('sha', 'md5')
+- The SNMPv3 encryption protocol (default: 'sha')
+
+Attributes
+
+hostname : str
+- The name or IP address of the device we want to guess the type
+snmp_version : str
+- The SNMP version that is running on the device
+snmp_port : int
+- The UDP port on which SNMP is listening
+community : str
+- The SNMP read community when using SNMPv2
+user : str
+- The SNMPv3 user for authentication
+auth_key : str
+- The SNMPv3 authentication key
+encrypt_key : str
+- The SNMPv3 encryption key
+auth_proto : str
+- The SNMPv3 authentication protocol
+encrypt_proto : str
+- The SNMPv3 encryption protocol
+
+Methods
+autodetect()
+Try to determine the device type.
+
+Source code
+class SNMPDetect(object):
+ """
+ The SNMPDetect class tries to automatically determine the device type.
+
+ Typically this will use the MIB-2 SysDescr and regular expressions.
+
+ Parameters
+ ----------
+ hostname: str
+ The name or IP address of the hostname we want to guess the type
+ snmp_version : str, optional ('v1', 'v2c' or 'v3')
+ The SNMP version that is running on the device (default: 'v3')
+ snmp_port : int, optional
+ The UDP port on which SNMP is listening (default: 161)
+ community : str, optional
+ The SNMP read community when using SNMPv2 (default: None)
+ user : str, optional
+ The SNMPv3 user for authentication (default: '')
+ auth_key : str, optional
+ The SNMPv3 authentication key (default: '')
+ encrypt_key : str, optional
+ The SNMPv3 encryption key (default: '')
+ auth_proto : str, optional ('des', '3des', 'aes128', 'aes192', 'aes256')
+ The SNMPv3 authentication protocol (default: 'aes128')
+ encrypt_proto : str, optional ('sha', 'md5')
+ The SNMPv3 encryption protocol (default: 'sha')
+
+ Attributes
+ ----------
+ hostname: str
+ The name or IP address of the device we want to guess the type
+ snmp_version : str
+ The SNMP version that is running on the device
+ snmp_port : int
+ The UDP port on which SNMP is listening
+ community : str
+ The SNMP read community when using SNMPv2
+ user : str
+ The SNMPv3 user for authentication
+ auth_key : str
+ The SNMPv3 authentication key
+ encrypt_key : str
+ The SNMPv3 encryption key
+ auth_proto : str
+ The SNMPv3 authentication protocol
+ encrypt_proto : str
+ The SNMPv3 encryption protocol
+
+ Methods
+ -------
+ autodetect()
+ Try to determine the device type.
+
+ """
+
+ def __init__(
+ self,
+ hostname: str,
+ snmp_version: str = "v3",
+ snmp_port: int = 161,
+ community: Optional[str] = None,
+ user: str = "",
+ auth_key: str = "",
+ encrypt_key: str = "",
+ auth_proto: str = "sha",
+ encrypt_proto: str = "aes128",
+ ) -> None:
+
+ # Check that the SNMP version is matching predefined type or raise ValueError
+ if snmp_version == "v1" or snmp_version == "v2c":
+ if not community:
+ raise ValueError("SNMP version v1/v2c community must be set.")
+ elif snmp_version == "v3":
+ if not user:
+ raise ValueError("SNMP version v3 user and password must be set")
+ else:
+ raise ValueError("SNMP version must be set to 'v1', 'v2c' or 'v3'")
+
+ # Check that the SNMPv3 auth & priv parameters match allowed types
+ self._snmp_v3_authentication = {
+ "sha": cmdgen.usmHMACSHAAuthProtocol,
+ "md5": cmdgen.usmHMACMD5AuthProtocol,
+ }
+ self._snmp_v3_encryption = {
+ "des": cmdgen.usmDESPrivProtocol,
+ "3des": cmdgen.usm3DESEDEPrivProtocol,
+ "aes128": cmdgen.usmAesCfb128Protocol,
+ "aes192": cmdgen.usmAesCfb192Protocol,
+ "aes256": cmdgen.usmAesCfb256Protocol,
+ }
+ if auth_proto not in self._snmp_v3_authentication.keys():
+ raise ValueError(
+ "SNMP V3 'auth_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_authentication.keys()
+ )
+ )
+ if encrypt_proto not in self._snmp_v3_encryption.keys():
+ raise ValueError(
+ "SNMP V3 'encrypt_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_encryption.keys()
+ )
+ )
+
+ self.hostname = hostname
+ self.snmp_version = snmp_version
+ self.snmp_port = snmp_port
+ self.community = community
+ self.user = user
+ self.auth_key = auth_key
+ self.encrypt_key = encrypt_key
+ self.auth_proto = self._snmp_v3_authentication[auth_proto]
+ self.encryp_proto = self._snmp_v3_encryption[encrypt_proto]
+ self._response_cache: Dict[str, str] = {}
+
+ def _get_snmpv3(self, oid: str) -> str:
+ """
+ Try to send an SNMP GET operation using SNMPv3 for the specified OID.
+
+ Parameters
+ ----------
+ oid : str
+ The SNMP OID that you want to get.
+
+ Returns
+ -------
+ string : str
+ The string as part of the value from the OID you are trying to retrieve.
+ """
+ snmp_target = (self.hostname, self.snmp_port)
+ cmd_gen = cmdgen.CommandGenerator()
+
+ (error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
+ cmdgen.UsmUserData(
+ self.user,
+ self.auth_key,
+ self.encrypt_key,
+ authProtocol=self.auth_proto,
+ privProtocol=self.encryp_proto,
+ ),
+ cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
+
+ if not error_detected and snmp_data[0][1]:
+ return str(snmp_data[0][1])
+ return ""
+
+ def _get_snmpv2c(self, oid: str) -> str:
+ """
+ Try to send an SNMP GET operation using SNMPv2 for the specified OID.
+
+ Parameters
+ ----------
+ oid : str
+ The SNMP OID that you want to get.
+
+ Returns
+ -------
+ string : str
+ The string as part of the value from the OID you are trying to retrieve.
+ """
+ snmp_target = (self.hostname, self.snmp_port)
+ cmd_gen = cmdgen.CommandGenerator()
+
+ (error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
+ cmdgen.CommunityData(self.community),
+ cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
+
+ if not error_detected and snmp_data[0][1]:
+ return str(snmp_data[0][1])
+ return ""
+
+ def _get_snmp(self, oid: str) -> str:
+ """Wrapper for generic SNMP call."""
+ if self.snmp_version in ["v1", "v2c"]:
+ return self._get_snmpv2c(oid)
+ else:
+ return self._get_snmpv3(oid)
+
+ def autodetect(self) -> Optional[str]:
+ """
+ Try to guess the device_type using SNMP GET based on the SNMP_MAPPER dict. The type which
+ is returned is directly matching the name in *netmiko.ssh_dispatcher.CLASS_MAPPER_BASE*
+ dict.
+
+ Thus you can use this name to retrieve automatically the right ConnectionClass
+
+ Returns
+ -------
+ potential_type : str
+ The name of the device_type that must be running.
+ """
+ # Convert SNMP_MAPPER to a list and sort by priority
+ snmp_mapper_orig = []
+ for k, v in SNMP_MAPPER.items():
+ snmp_mapper_orig.append({k: v})
+ snmp_mapper_list = sorted(
+ snmp_mapper_orig, key=lambda x: list(x.values())[0]["priority"] # type: ignore
+ )
+ snmp_mapper_list.reverse()
+
+ for entry in snmp_mapper_list:
+ for device_type, v in entry.items():
+ oid: str = v["oid"] # type: ignore
+ regex: Pattern = v["expr"]
+
+ # Used cache data if we already queryied this OID
+ if self._response_cache.get(oid):
+ snmp_response = self._response_cache.get(oid)
+ else:
+ snmp_response = self._get_snmp(oid)
+ self._response_cache[oid] = snmp_response
+
+ # See if we had a match
+ if re.search(regex, snmp_response):
+ assert isinstance(device_type, str)
+ return device_type
+
+ return None
+
+Methods
+
+
+def autodetect(self)
+
+-
+
Try to guess the device_type using SNMP GET based on the SNMP_MAPPER dict. The type which
+is returned is directly matching the name in netmiko.ssh_dispatcher.CLASS_MAPPER_BASE
+dict.
+Thus you can use this name to retrieve automatically the right ConnectionClass
+Returns
+
+potential_type : str
+- The name of the device_type that must be running.
+
+
+Source code
+def autodetect(self) -> Optional[str]:
+ """
+ Try to guess the device_type using SNMP GET based on the SNMP_MAPPER dict. The type which
+ is returned is directly matching the name in *netmiko.ssh_dispatcher.CLASS_MAPPER_BASE*
+ dict.
+
+ Thus you can use this name to retrieve automatically the right ConnectionClass
+
+ Returns
+ -------
+ potential_type : str
+ The name of the device_type that must be running.
+ """
+ # Convert SNMP_MAPPER to a list and sort by priority
+ snmp_mapper_orig = []
+ for k, v in SNMP_MAPPER.items():
+ snmp_mapper_orig.append({k: v})
+ snmp_mapper_list = sorted(
+ snmp_mapper_orig, key=lambda x: list(x.values())[0]["priority"] # type: ignore
+ )
+ snmp_mapper_list.reverse()
+
+ for entry in snmp_mapper_list:
+ for device_type, v in entry.items():
+ oid: str = v["oid"] # type: ignore
+ regex: Pattern = v["expr"]
+
+ # Used cache data if we already queryied this OID
+ if self._response_cache.get(oid):
+ snmp_response = self._response_cache.get(oid)
+ else:
+ snmp_response = self._get_snmp(oid)
+ self._response_cache[oid] = snmp_response
+
+ # See if we had a match
+ if re.search(regex, snmp_response):
+ assert isinstance(device_type, str)
+ return device_type
+
+ return None
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/sophos/index.html b/docs/netmiko/sophos/index.html
new file mode 100644
index 000000000..6b7b0b883
--- /dev/null
+++ b/docs/netmiko/sophos/index.html
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+netmiko.sophos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.sophos.sophos_sfos_ssh import SophosSfosSSH
+
+__all__ = ["SophosSfosSSH"]
+
+
+
+
+
+
+
+
+
+class SophosSfosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SophosSfosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/sophos/sophos_sfos_ssh.html b/docs/netmiko/sophos/sophos_sfos_ssh.html
new file mode 100644
index 000000000..85d1af375
--- /dev/null
+++ b/docs/netmiko/sophos/sophos_sfos_ssh.html
@@ -0,0 +1,363 @@
+
+
+
+
+
+
+netmiko.sophos.sophos_sfos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.sophos.sophos_sfos_ssh
+
+
+SophosXG (SFOS) Firewall support
+
+Source code
+"""SophosXG (SFOS) Firewall support"""
+import time
+from typing import Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class SophosSfosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class SophosSfosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SophosSfosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Methods
+
+
+def save_config(self, *args, **kwargs)
+
+-
+
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ssh_auth.html b/docs/netmiko/ssh_auth.html
new file mode 100644
index 000000000..3d3fe4ce8
--- /dev/null
+++ b/docs/netmiko/ssh_auth.html
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+netmiko.ssh_auth API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ssh_auth
+
+
+
+Source code
+from typing import Any
+from paramiko import SSHClient
+
+
+class SSHClient_noauth(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def _auth(self, username: str, *args: Any) -> None:
+ transport = self.get_transport()
+ assert transport is not None
+ transport.auth_none(username)
+ return
+
+
+
+
+
+
+
+
+
+class SSHClient_noauth
+
+-
+
Set noauth when manually handling SSH authentication.
+Create a new SSHClient.
+
+Source code
+class SSHClient_noauth(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def _auth(self, username: str, *args: Any) -> None:
+ transport = self.get_transport()
+ assert transport is not None
+ transport.auth_none(username)
+ return
+
+Ancestors
+
+- paramiko.client.SSHClient
+- paramiko.util.ClosingContextManager
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ssh_autodetect.html b/docs/netmiko/ssh_autodetect.html
new file mode 100644
index 000000000..98438505d
--- /dev/null
+++ b/docs/netmiko/ssh_autodetect.html
@@ -0,0 +1,900 @@
+
+
+
+
+
+
+netmiko.ssh_autodetect API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ssh_autodetect
+
+
+The ssh_autodetect module is used to auto-detect the netmiko device_type to use to further initiate
+a new SSH connection with a remote host. This auto-detection is based on a unique class called
+SSHDetect.
+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 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.
+
+- "cmd" : The command to send to the remote device. The command output must not require paging.
+- "search_patterns" : A list of regex to compare with the output of the command
+- "priority" : An integer (0-99) which specifies the confidence of the match above
+- "dispatch" : The function to call to try the autodetection (per default SSHDetect._autodetect_std)
+
+Examples
+Auto-detection section
+>>> from netmiko.ssh_autodetect import SSHDetect
+>>> from netmiko.ssh_dispatcher import ConnectHandler
+>>> remote_device = {'device_type': 'autodetect',
+ 'host': 'remote.host',
+
+
+ 'username': 'test',
+ 'password': 'foo'}
+
+>>> guesser = SSHDetect(**remote_device)
+>>> best_match = guesser.autodetect()
+>>> print(best_match) # Name of the best device_type to use further
+>>> print(guesser.potential_matches) # Dictionary of the whole matching result
+
+Netmiko connection creation section
+>>> remote_device['device_type'] = best_match
+>>> connection = ConnectHandler(**remote_device)
+
+
+Source code
+"""
+The ssh_autodetect module is used to auto-detect the netmiko device_type to use to further initiate
+a new SSH connection with a remote host. This auto-detection is based on a unique class called
+**SSHDetect**.
+
+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 *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.
+
+* "cmd" : The command to send to the remote device. **The command output must not require paging.**
+* "search_patterns" : A list of regex to compare with the output of the command
+* "priority" : An integer (0-99) which specifies the confidence of the match above
+* "dispatch" : The function to call to try the autodetection (per default SSHDetect._autodetect_std)
+
+Examples
+--------
+
+# Auto-detection section
+>>> from netmiko.ssh_autodetect import SSHDetect
+>>> from netmiko.ssh_dispatcher import ConnectHandler
+>>> remote_device = {'device_type': 'autodetect',
+ 'host': 'remote.host',
+ 'username': 'test',
+ 'password': 'foo'}
+>>> guesser = SSHDetect(**remote_device)
+>>> best_match = guesser.autodetect()
+>>> print(best_match) # Name of the best device_type to use further
+>>> print(guesser.potential_matches) # Dictionary of the whole matching result
+
+# Netmiko connection creation section
+>>> remote_device['device_type'] = best_match
+>>> connection = ConnectHandler(**remote_device)
+"""
+from typing import Any, List, Optional, Union, Dict
+import re
+import time
+
+import paramiko
+
+from netmiko.ssh_dispatcher import ConnectHandler
+from netmiko.base_connection import BaseConnection
+
+
+# 'dispatch' key is the SSHDetect method to call. dispatch key will be popped off dictionary
+# remaining keys indicate kwargs that will be passed to dispatch method.
+# Note, the 'cmd' needs to avoid output paging.
+SSH_MAPPER_DICT = {
+ "alcatel_aos": {
+ "cmd": "show system",
+ "search_patterns": [r"Alcatel-Lucent"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "alcatel_sros": {
+ "cmd": "show version",
+ "search_patterns": ["Nokia", "Alcatel"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "apresia_aeos": {
+ "cmd": "show system",
+ "search_patterns": ["Apresia"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "arista_eos": {
+ "cmd": "show version",
+ "search_patterns": [r"Arista"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "ciena_saos": {
+ "cmd": "software show",
+ "search_patterns": [r"saos"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_asa": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco Adaptive Security Appliance", r"Cisco ASA"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_ios": {
+ "cmd": "show version",
+ "search_patterns": [
+ "Cisco IOS Software",
+ "Cisco Internetwork Operating System Software",
+ ],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_nxos": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco Nexus Operating System", r"NX-OS"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_xr": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco IOS XR"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_force10": {
+ "cmd": "show version",
+ "search_patterns": [r"Real Time Operating System Software"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_os9": {
+ "cmd": "show system",
+ "search_patterns": [
+ r"Dell Application Software Version: 9",
+ r"Dell Networking OS Version : 9",
+ ],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_os10": {
+ "cmd": "show version",
+ "search_patterns": [r"Dell EMC Networking OS10.Enterprise"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_powerconnect": {
+ "cmd": "show system",
+ "search_patterns": [r"PowerConnect"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "f5_tmsh": {
+ "cmd": "show sys version",
+ "search_patterns": [r"BIG-IP"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "f5_linux": {
+ "cmd": "cat /etc/issue",
+ "search_patterns": [r"BIG-IP"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "hp_comware": {
+ "cmd": "display version",
+ "search_patterns": ["HPE Comware", "HP Comware"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "huawei": {
+ "cmd": "display version",
+ "search_patterns": [
+ r"Huawei Technologies",
+ r"Huawei Versatile Routing Platform Software",
+ ],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "juniper_junos": {
+ "cmd": "show version",
+ "search_patterns": [
+ r"JUNOS Software Release",
+ r"JUNOS .+ Software",
+ r"JUNOS OS Kernel",
+ r"JUNOS Base Version",
+ ],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "linux": {
+ "cmd": "uname -a",
+ "search_patterns": [r"Linux"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_exos": {
+ "cmd": "show version",
+ "search_patterns": [r"ExtremeXOS"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_netiron": {
+ "cmd": "show version",
+ "search_patterns": [r"(NetIron|MLX)"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_slx": {
+ "cmd": "show version",
+ "search_patterns": [r"SLX-OS Operating System Software"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_tierra": {
+ "cmd": "show version",
+ "search_patterns": [r"TierraOS Software"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "ubiquiti_edgeswitch": {
+ "cmd": "show version",
+ "search_patterns": [r"EdgeSwitch"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_wlc": {
+ "cmd": "",
+ "dispatch": "_autodetect_remote_version",
+ "search_patterns": [r"CISCO_WLC"],
+ "priority": 99,
+ },
+ "cisco_wlc_85": {
+ "cmd": "show inventory",
+ "dispatch": "_autodetect_std",
+ "search_patterns": [r"Cisco Wireless Controller"],
+ "priority": 99,
+ },
+ "mellanox_mlnxos": {
+ "cmd": "show version",
+ "search_patterns": [r"Onyx", r"SX_PPC_M460EX"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "yamaha": {
+ "cmd": "show copyright",
+ "search_patterns": [r"Yamaha Corporation"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "fortinet": {
+ "cmd": "get system status",
+ "search_patterns": [r"FortiOS"],
+ "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_DICT such that the most common commands are first
+cmd_count: Dict[str, int] = {}
+for k, v in SSH_MAPPER_DICT.items():
+ my_cmd = v["cmd"]
+ assert isinstance(my_cmd, str)
+ count = cmd_count.setdefault(my_cmd, 0)
+ cmd_count[my_cmd] = count + 1
+cmd_count = {k: v for k, v in sorted(cmd_count.items(), key=lambda item: item[1])}
+
+# SSH_MAPPER_BASE is a list
+SSH_MAPPER_BASE = sorted(
+ SSH_MAPPER_DICT.items(), key=lambda item: int(cmd_count[str(item[1]["cmd"])])
+)
+SSH_MAPPER_BASE.reverse()
+
+
+class SSHDetect(object):
+ """
+ The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
+ Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
+ all.
+
+ Parameters
+ ----------
+ *args : list
+ The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+ *kwargs : dict
+ The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+
+ Attributes
+ ----------
+ connection : netmiko.terminal_server.TerminalServerSSH
+ A basic connection to the remote SSH end.
+ potential_matches: dict
+ Dict of (device_type, accuracy) that is populated through an interaction with the
+ remote end.
+
+ Methods
+ -------
+ autodetect()
+ Try to determine the device type.
+ """
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """
+ Constructor of the SSHDetect class
+ """
+ if kwargs["device_type"] != "autodetect":
+ raise ValueError("The connection device_type must be 'autodetect'")
+ # Always set cmd_verify to False for autodetect
+ kwargs["global_cmd_verify"] = False
+ self.connection = ConnectHandler(*args, **kwargs)
+ # Call the _test_channel_read() in base to clear initial data
+ output = BaseConnection._test_channel_read(self.connection)
+ self.initial_buffer = output
+ self.potential_matches: Dict[str, int] = {}
+ self._results_cache: Dict[str, str] = {}
+
+ def autodetect(self) -> Union[str, None]:
+ """
+ Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+
+ 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:
+ tmp_dict = autodetect_dict.copy()
+ call_method = tmp_dict.pop("dispatch")
+ assert isinstance(call_method, str)
+ autodetect_method = getattr(self, call_method)
+ accuracy = autodetect_method(**tmp_dict)
+ if accuracy:
+ self.potential_matches[device_type] = accuracy
+ if accuracy >= 99: # Stop the loop as we are sure of our match
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ if not self.potential_matches:
+ self.connection.disconnect()
+ return None
+
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ def _send_command(self, cmd: str = "") -> str:
+ """
+ Handle reading/writing channel directly. It is also sanitizing the output received.
+
+ Parameters
+ ----------
+ cmd : str, optional
+ The command to send to the remote device (default : "", just send a new line)
+
+ Returns
+ -------
+ output : str
+ The output from the command sent
+ """
+ self.connection.write_channel(cmd + "\n")
+ time.sleep(1)
+ output = self.connection.read_channel_timing()
+ output = self.connection.strip_backspaces(output)
+ return output
+
+ def _send_command_wrapper(self, cmd: str) -> str:
+ """
+ Send command to the remote device with a caching feature to avoid sending the same command
+ twice based on the SSH_MAPPER_BASE dict cmd key.
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+
+ Returns
+ -------
+ response : str
+ The response from the remote device.
+ """
+ cached_results = self._results_cache.get(cmd)
+ if not cached_results:
+ response = self._send_command(cmd)
+ self._results_cache[cmd] = response
+ return response
+ else:
+ return cached_results
+
+ def _autodetect_remote_version(
+ self,
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ **kwargs: Any
+ ) -> int:
+ """
+ Method to try auto-detect the device type, by matching a regular expression on the reported
+ remote version of the SSH server.
+
+ Parameters
+ ----------
+ search_patterns : list
+ A list of regular expression to look for in the reported remote SSH version
+ (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [r"^$"]
+
+ if not search_patterns:
+ return 0
+
+ try:
+ remote_conn = self.connection.remote_conn
+ assert isinstance(remote_conn, paramiko.Channel)
+ assert remote_conn.transport is not None
+ remote_version = remote_conn.transport.remote_version
+ for pattern in invalid_responses:
+ match = re.search(pattern, remote_version, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, remote_version, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+ def _autodetect_std(
+ self,
+ cmd: str = "",
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ ) -> int:
+ """
+ Standard method to try to auto-detect the device type. This method will be called for each
+ device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
+ command and match some regular expression from the ouput for each entry in SSH_MAPPER_BASE
+ ('cmd' and 'search_pattern' keys).
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+ search_patterns : list
+ A list of regular expression to look for in the command's output (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [
+ r"% Invalid input detected",
+ r"syntax error, expecting",
+ r"Error: Unrecognized command",
+ r"%Error",
+ r"command not found",
+ r"Syntax Error: unexpected argument",
+ r"% Unrecognized command found at",
+ ]
+ if not cmd or not search_patterns:
+ return 0
+ try:
+ # _send_command_wrapper will use already cached results if available
+ response = self._send_command_wrapper(cmd)
+ # Look for error conditions in output
+ for pattern in invalid_responses:
+ match = re.search(pattern, response, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, response, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+
+
+
+
+
+
+
+
+class SSHDetect
+(*args, **kwargs)
+
+-
+
The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
+Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
+all.
+Parameters
+
+*args : list
+- The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+*kwargs : dict
+- The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+
+Attributes
+
+connection : TerminalServerSSH
+- A basic connection to the remote SSH end.
+potential_matches : dict
+- Dict of (device_type, accuracy) that is populated through an interaction with the
+remote end.
+
+Methods
+autodetect()
+Try to determine the device type.
+Constructor of the SSHDetect class
+
+Source code
+class SSHDetect(object):
+ """
+ The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
+ Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
+ all.
+
+ Parameters
+ ----------
+ *args : list
+ The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+ *kwargs : dict
+ The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
+
+ Attributes
+ ----------
+ connection : netmiko.terminal_server.TerminalServerSSH
+ A basic connection to the remote SSH end.
+ potential_matches: dict
+ Dict of (device_type, accuracy) that is populated through an interaction with the
+ remote end.
+
+ Methods
+ -------
+ autodetect()
+ Try to determine the device type.
+ """
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """
+ Constructor of the SSHDetect class
+ """
+ if kwargs["device_type"] != "autodetect":
+ raise ValueError("The connection device_type must be 'autodetect'")
+ # Always set cmd_verify to False for autodetect
+ kwargs["global_cmd_verify"] = False
+ self.connection = ConnectHandler(*args, **kwargs)
+ # Call the _test_channel_read() in base to clear initial data
+ output = BaseConnection._test_channel_read(self.connection)
+ self.initial_buffer = output
+ self.potential_matches: Dict[str, int] = {}
+ self._results_cache: Dict[str, str] = {}
+
+ def autodetect(self) -> Union[str, None]:
+ """
+ Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+
+ 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:
+ tmp_dict = autodetect_dict.copy()
+ call_method = tmp_dict.pop("dispatch")
+ assert isinstance(call_method, str)
+ autodetect_method = getattr(self, call_method)
+ accuracy = autodetect_method(**tmp_dict)
+ if accuracy:
+ self.potential_matches[device_type] = accuracy
+ if accuracy >= 99: # Stop the loop as we are sure of our match
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ if not self.potential_matches:
+ self.connection.disconnect()
+ return None
+
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ def _send_command(self, cmd: str = "") -> str:
+ """
+ Handle reading/writing channel directly. It is also sanitizing the output received.
+
+ Parameters
+ ----------
+ cmd : str, optional
+ The command to send to the remote device (default : "", just send a new line)
+
+ Returns
+ -------
+ output : str
+ The output from the command sent
+ """
+ self.connection.write_channel(cmd + "\n")
+ time.sleep(1)
+ output = self.connection.read_channel_timing()
+ output = self.connection.strip_backspaces(output)
+ return output
+
+ def _send_command_wrapper(self, cmd: str) -> str:
+ """
+ Send command to the remote device with a caching feature to avoid sending the same command
+ twice based on the SSH_MAPPER_BASE dict cmd key.
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+
+ Returns
+ -------
+ response : str
+ The response from the remote device.
+ """
+ cached_results = self._results_cache.get(cmd)
+ if not cached_results:
+ response = self._send_command(cmd)
+ self._results_cache[cmd] = response
+ return response
+ else:
+ return cached_results
+
+ def _autodetect_remote_version(
+ self,
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ **kwargs: Any
+ ) -> int:
+ """
+ Method to try auto-detect the device type, by matching a regular expression on the reported
+ remote version of the SSH server.
+
+ Parameters
+ ----------
+ search_patterns : list
+ A list of regular expression to look for in the reported remote SSH version
+ (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [r"^$"]
+
+ if not search_patterns:
+ return 0
+
+ try:
+ remote_conn = self.connection.remote_conn
+ assert isinstance(remote_conn, paramiko.Channel)
+ assert remote_conn.transport is not None
+ remote_version = remote_conn.transport.remote_version
+ for pattern in invalid_responses:
+ match = re.search(pattern, remote_version, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, remote_version, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+ def _autodetect_std(
+ self,
+ cmd: str = "",
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ ) -> int:
+ """
+ Standard method to try to auto-detect the device type. This method will be called for each
+ device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
+ command and match some regular expression from the ouput for each entry in SSH_MAPPER_BASE
+ ('cmd' and 'search_pattern' keys).
+
+ Parameters
+ ----------
+ cmd : str
+ The command to send to the remote device after checking cache.
+ search_patterns : list
+ A list of regular expression to look for in the command's output (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [
+ r"% Invalid input detected",
+ r"syntax error, expecting",
+ r"Error: Unrecognized command",
+ r"%Error",
+ r"command not found",
+ r"Syntax Error: unexpected argument",
+ r"% Unrecognized command found at",
+ ]
+ if not cmd or not search_patterns:
+ return 0
+ try:
+ # _send_command_wrapper will use already cached results if available
+ response = self._send_command_wrapper(cmd)
+ # Look for error conditions in output
+ for pattern in invalid_responses:
+ match = re.search(pattern, response, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, response, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+Methods
+
+
+def autodetect(self)
+
+-
+
Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+Returns
+
+best_match : str or None
+- The device type that is currently the best to use to interact with the device
+
+
+Source code
+def autodetect(self) -> Union[str, None]:
+ """
+ Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
+
+ 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:
+ tmp_dict = autodetect_dict.copy()
+ call_method = tmp_dict.pop("dispatch")
+ assert isinstance(call_method, str)
+ autodetect_method = getattr(self, call_method)
+ accuracy = autodetect_method(**tmp_dict)
+ if accuracy:
+ self.potential_matches[device_type] = accuracy
+ if accuracy >= 99: # Stop the loop as we are sure of our match
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
+ self.connection.disconnect()
+ return best_match[0][0]
+
+ if not self.potential_matches:
+ self.connection.disconnect()
+ return None
+
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ self.connection.disconnect()
+ return best_match[0][0]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ssh_exception.html b/docs/netmiko/ssh_exception.html
new file mode 100644
index 000000000..ebadb55ba
--- /dev/null
+++ b/docs/netmiko/ssh_exception.html
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+netmiko.ssh_exception API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ssh_exception
+
+
+
+Source code
+from paramiko.ssh_exception import SSHException
+from paramiko.ssh_exception import AuthenticationException
+
+
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+
+class ConfigInvalidException(Exception):
+ """Exception raised for invalid configuration error."""
+
+ pass
+
+
+NetMikoTimeoutException = NetmikoTimeoutException
+NetMikoAuthenticationException = NetmikoAuthenticationException
+
+
+
+
+
+
+
+
+
+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)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetMikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoAuthenticationException
+(*args, **kwargs)
+
+-
+
SSH authentication exception based on Paramiko AuthenticationException.
+
+Source code
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.AuthenticationException
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+class NetmikoTimeoutException
+(*args, **kwargs)
+
+-
+
SSH session timed trying to connect to the device.
+
+Source code
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+Ancestors
+
+- paramiko.ssh_exception.SSHException
+- builtins.Exception
+- builtins.BaseException
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/supermicro/index.html b/docs/netmiko/supermicro/index.html
new file mode 100644
index 000000000..2e888cb54
--- /dev/null
+++ b/docs/netmiko/supermicro/index.html
@@ -0,0 +1,438 @@
+
+
+
+
+
+
+netmiko.supermicro API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.supermicro
+
+
+
+Source code
+from netmiko.supermicro.smci_smis import SmciSwitchSmisTelnet, SmciSwitchSmisSSH
+
+__all__ = ["SmciSwitchSmisSSH", "SmciSwitchSmisTelnet"]
+
+
+
+
+
+
+
+
+
+class SmciSwitchSmisSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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..8a0bed97b
--- /dev/null
+++ b/docs/netmiko/supermicro/smci_smis.html
@@ -0,0 +1,716 @@
+
+
+
+
+
+
+netmiko.supermicro.smci_smis API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.supermicro.smci_smis
+
+
+
+Source code
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.no_enable import NoEnable
+import time
+
+
+class SmciSwitchSmisBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """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: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def save_config(
+ self,
+ cmd: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class SmciSwitchSmisSSH(SmciSwitchSmisBase):
+ pass
+
+
+class SmciSwitchSmisTelnet(SmciSwitchSmisBase):
+ pass
+
+
+
+
+
+
+
+
+
+class SmciSwitchSmisBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class SmciSwitchSmisBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """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: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def save_config(
+ self,
+ cmd: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def save_config(self, cmd='write startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """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) -> None:
+ """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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+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
new file mode 100644
index 000000000..a2f6147a1
--- /dev/null
+++ b/docs/netmiko/terminal_server/index.html
@@ -0,0 +1,447 @@
+
+
+
+
+
+
+netmiko.terminal_server API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.terminal_server
+
+
+
+Source code
+from netmiko.terminal_server.terminal_server import TerminalServerSSH
+from netmiko.terminal_server.terminal_server import TerminalServerTelnet
+
+__all__ = ["TerminalServerSSH", "TerminalServerTelnet"]
+
+
+
+
+
+
+
+
+
+-
+
Generic Terminal Server driver SSH.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TerminalServerSSH(TerminalServer):
+ """Generic Terminal Server driver SSH."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class TerminalServerTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Generic Terminal Server driver telnet.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TerminalServerTelnet(TerminalServer):
+ """Generic Terminal Server driver telnet."""
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # Disable automatic handling of username and password when using terminal server driver
+ pass
+
+ def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Methods
+
+
+def std_login(self, *args, **kwargs)
+
+-
+
+
+Source code
+def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/terminal_server/terminal_server.html b/docs/netmiko/terminal_server/terminal_server.html
new file mode 100644
index 000000000..609ba1d99
--- /dev/null
+++ b/docs/netmiko/terminal_server/terminal_server.html
@@ -0,0 +1,667 @@
+
+
+
+
+
+
+netmiko.terminal_server.terminal_server API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.terminal_server.terminal_server
+
+
+Generic Terminal Server driver.
+
+Source code
+"""Generic Terminal Server driver."""
+from typing import Any
+
+from netmiko.base_connection import BaseConnection
+
+
+class TerminalServer(BaseConnection):
+ """Generic Terminal Server driver.
+
+ Allow direct write_channel / read_channel operations without session_preparation causing
+ an exception.
+ """
+
+ def session_preparation(self) -> None:
+ """Do nothing here; base_prompt is not set; paging is not disabled."""
+ pass
+
+
+class TerminalServerSSH(TerminalServer):
+ """Generic Terminal Server driver SSH."""
+
+ pass
+
+
+class TerminalServerTelnet(TerminalServer):
+ """Generic Terminal Server driver telnet."""
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # Disable automatic handling of username and password when using terminal server driver
+ pass
+
+ def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class TerminalServer
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Generic Terminal Server driver.
+Allow direct write_channel / read_channel operations without session_preparation causing
+an exception.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TerminalServer(BaseConnection):
+ """Generic Terminal Server driver.
+
+ Allow direct write_channel / read_channel operations without session_preparation causing
+ an exception.
+ """
+
+ def session_preparation(self) -> None:
+ """Do nothing here; base_prompt is not set; paging is not disabled."""
+ pass
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Do nothing here; base_prompt is not set; paging is not disabled.
+
+Source code
+def session_preparation(self) -> None:
+ """Do nothing here; base_prompt is not set; paging is not disabled."""
+ pass
+
+
+
+Inherited members
+
+
+
+-
+
Generic Terminal Server driver SSH.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TerminalServerSSH(TerminalServer):
+ """Generic Terminal Server driver SSH."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class TerminalServerTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Generic Terminal Server driver telnet.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TerminalServerTelnet(TerminalServer):
+ """Generic Terminal Server driver telnet."""
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # Disable automatic handling of username and password when using terminal server driver
+ pass
+
+ def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Methods
+
+
+def std_login(self, *args, **kwargs)
+
+-
+
+
+Source code
+def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/tplink/index.html b/docs/netmiko/tplink/index.html
new file mode 100644
index 000000000..dd01b0d60
--- /dev/null
+++ b/docs/netmiko/tplink/index.html
@@ -0,0 +1,499 @@
+
+
+
+
+
+
+netmiko.tplink API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.tplink.tplink_jetstream import TPLinkJetStreamSSH, TPLinkJetStreamTelnet
+
+__all__ = ["TPLinkJetStreamSSH", "TPLinkJetStreamTelnet"]
+
+
+
+
+
+
+
+
+
+class TPLinkJetStreamSSH
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+ def __init__(self, **kwargs: Any) -> None:
+ setattr(dsa, "_check_dsa_parameters", self._override_check_dsa_parameters)
+ return super().__init__(**kwargs)
+
+ def _override_check_dsa_parameters(self, parameters: DSAParameterNumbers) -> None:
+ """
+ Override check_dsa_parameters from cryptography's dsa.py
+
+ Without this the error below occurs:
+
+ ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+ Allows for shorter or longer parameters.p to be returned
+ from the server's host key. This is a HORRIBLE hack and a
+ security risk, please remove if possible!
+
+ By now, with firmware:
+
+ 2.0.5 Build 20200109 Rel.36203(s)
+
+ It's still not possible to remove this hack.
+ """
+ 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.")
+
+Ancestors
+
+Inherited members
+
+
+
+class TPLinkJetStreamTelnet
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='User:', pwd_pattern='Password:', delay_factor=1.0, max_loops=60)
+
+-
+
Telnet login: can be username/password or just password.
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/tplink/tplink_jetstream.html b/docs/netmiko/tplink/tplink_jetstream.html
new file mode 100644
index 000000000..18e35708c
--- /dev/null
+++ b/docs/netmiko/tplink/tplink_jetstream.html
@@ -0,0 +1,1146 @@
+
+
+
+
+
+
+netmiko.tplink.tplink_jetstream API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.tplink.tplink_jetstream
+
+
+
+Source code
+import re
+import time
+from typing import Any, Optional
+
+from cryptography.hazmat.primitives.asymmetric import dsa
+from cryptography.hazmat.primitives.asymmetric.dsa import DSAParameterNumbers
+
+from netmiko import log
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.exceptions import NetmikoTimeoutException
+
+
+class TPLinkJetStreamBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # TP-Link doesn't have a way to set terminal width which breaks cmd_verify
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ # TP-Link uses "\r\n" as default_enter for SSH and Telnet
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """
+ TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+ This is necessary as "configure" is generally only available at "enable-admin" level
+
+ If the user does not have the Admin role, he will need to execute enable-admin to really
+ enable all functions.
+ """
+
+ # If end-user passes in "cmd" execute that using normal process.
+ if cmd:
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ output = ""
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+
+ cmds = ["enable", "enable-admin"]
+ if not self.check_enable_mode():
+ for cmd in cmds:
+ self.write_channel(self.normalize_cmd(cmd))
+ try:
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_prompt(read_entire_line=True)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#") -> str:
+ """
+ Exit config mode.
+
+ Like the Mellanox equipment, the TP-Link Jetstream does not
+ support a single command to completely exit the configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple
+ contexts. For TP-Link this will be the router prompt with > or #
+ stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+ def __init__(self, **kwargs: Any) -> None:
+ setattr(dsa, "_check_dsa_parameters", self._override_check_dsa_parameters)
+ return super().__init__(**kwargs)
+
+ def _override_check_dsa_parameters(self, parameters: DSAParameterNumbers) -> None:
+ """
+ Override check_dsa_parameters from cryptography's dsa.py
+
+ Without this the error below occurs:
+
+ ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+ Allows for shorter or longer parameters.p to be returned
+ from the server's host key. This is a HORRIBLE hack and a
+ security risk, please remove if possible!
+
+ By now, with firmware:
+
+ 2.0.5 Build 20200109 Rel.36203(s)
+
+ It's still not possible to remove this hack.
+ """
+ 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.")
+
+
+class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+
+
+
+
+
+
+class TPLinkJetStreamBase
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TPLinkJetStreamBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # TP-Link doesn't have a way to set terminal width which breaks cmd_verify
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ # TP-Link uses "\r\n" as default_enter for SSH and Telnet
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """
+ TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+ This is necessary as "configure" is generally only available at "enable-admin" level
+
+ If the user does not have the Admin role, he will need to execute enable-admin to really
+ enable all functions.
+ """
+
+ # If end-user passes in "cmd" execute that using normal process.
+ if cmd:
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ output = ""
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+
+ cmds = ["enable", "enable-admin"]
+ if not self.check_enable_mode():
+ for cmd in cmds:
+ self.write_channel(self.normalize_cmd(cmd))
+ try:
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_prompt(read_entire_line=True)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#") -> str:
+ """
+ Exit config mode.
+
+ Like the Mellanox equipment, the TP-Link Jetstream does not
+ support a single command to completely exit the configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple
+ contexts. For TP-Link this will be the router prompt with > or #
+ stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='(config', pattern='#')
+
+-
+
Check whether device is in configuration mode. Return a boolean.
+
+Source code
+def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+) -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def enable(self, cmd='', pattern='ssword', enable_pattern=None, re_flags=)
+
+-
+
TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+This is necessary as "configure" is generally only available at "enable-admin" level
+If the user does not have the Admin role, he will need to execute enable-admin to really
+enable all functions.
+
+Source code
+def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+) -> str:
+ """
+ TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+ This is necessary as "configure" is generally only available at "enable-admin" level
+
+ If the user does not have the Admin role, he will need to execute enable-admin to really
+ enable all functions.
+ """
+
+ # If end-user passes in "cmd" execute that using normal process.
+ if cmd:
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ output = ""
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+
+ cmds = ["enable", "enable-admin"]
+ if not self.check_enable_mode():
+ for cmd in cmds:
+ self.write_channel(self.normalize_cmd(cmd))
+ try:
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_prompt(read_entire_line=True)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='#')
+
+-
+
Exit config mode.
+Like the Mellanox equipment, the TP-Link Jetstream does not
+support a single command to completely exit the configuration mode.
+Consequently, need to keep checking and sending "exit".
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#") -> str:
+ """
+ Exit config mode.
+
+ Like the Mellanox equipment, the TP-Link Jetstream does not
+ support a single command to completely exit the configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+
+ return output
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt
+Used as delimiter for stripping of trailing prompt in output.
+Should be set to something that is general and applies in multiple
+contexts. For TP-Link this will be the router prompt with > or #
+stripped off.
+This will be set on logging in, but not when entering system-view
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple
+ contexts. For TP-Link this will be the router prompt with > or #
+ stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+
+Inherited members
+
+
+
+class TPLinkJetStreamSSH
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+ def __init__(self, **kwargs: Any) -> None:
+ setattr(dsa, "_check_dsa_parameters", self._override_check_dsa_parameters)
+ return super().__init__(**kwargs)
+
+ def _override_check_dsa_parameters(self, parameters: DSAParameterNumbers) -> None:
+ """
+ Override check_dsa_parameters from cryptography's dsa.py
+
+ Without this the error below occurs:
+
+ ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+ Allows for shorter or longer parameters.p to be returned
+ from the server's host key. This is a HORRIBLE hack and a
+ security risk, please remove if possible!
+
+ By now, with firmware:
+
+ 2.0.5 Build 20200109 Rel.36203(s)
+
+ It's still not possible to remove this hack.
+ """
+ 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.")
+
+Ancestors
+
+Inherited members
+
+
+
+class TPLinkJetStreamTelnet
+(**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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+Ancestors
+
+Methods
+
+
+def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='User:', pwd_pattern='Password:', delay_factor=1.0, max_loops=60)
+
+-
+
Telnet login: can be username/password or just password.
+
+Source code
+def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/edge_ssh.html b/docs/netmiko/ubiquiti/edge_ssh.html
new file mode 100644
index 000000000..8383cee0a
--- /dev/null
+++ b/docs/netmiko/ubiquiti/edge_ssh.html
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+netmiko.ubiquiti.edge_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ubiquiti.edge_ssh
+
+
+
+Source code
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class UbiquitiEdgeSSH(CiscoSSHConnection):
+ """
+ Implements support for Ubiquity EdgeSwitch devices.
+
+ Mostly conforms to Cisco IOS style syntax with a few minor changes.
+
+ This is NOT for EdgeRouter devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+
+
+
+
+
+
+class UbiquitiEdgeSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Ubiquity EdgeSwitch devices.
+Mostly conforms to Cisco IOS style syntax with a few minor changes.
+This is NOT for EdgeRouter devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiEdgeSSH(CiscoSSHConnection):
+ """
+ Implements support for Ubiquity EdgeSwitch devices.
+
+ Mostly conforms to Cisco IOS style syntax with a few minor changes.
+
+ This is NOT for EdgeRouter devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+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: str = ")#", pattern: str = "") -> bool:
+ """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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='#.*')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/edgerouter_ssh.html b/docs/netmiko/ubiquiti/edgerouter_ssh.html
new file mode 100644
index 000000000..810feb636
--- /dev/null
+++ b/docs/netmiko/ubiquiti/edgerouter_ssh.html
@@ -0,0 +1,309 @@
+
+
+
+
+
+
+netmiko.ubiquiti.edgerouter_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ubiquiti.edgerouter_ssh
+
+
+
+Source code
+import time
+from netmiko.vyos.vyos_ssh import VyOSSSH
+
+
+class UbiquitiEdgeRouterSSH(VyOSSSH):
+ """Implement methods for interacting with EdgeOS EdgeRouter network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
+
+
+
+
+
+
+
+
+
+-
+
Implement methods for interacting with EdgeOS EdgeRouter network devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiEdgeRouterSSH(VyOSSSH):
+ """Implement methods for interacting with EdgeOS EdgeRouter network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/index.html b/docs/netmiko/ubiquiti/index.html
new file mode 100644
index 000000000..17a814f28
--- /dev/null
+++ b/docs/netmiko/ubiquiti/index.html
@@ -0,0 +1,864 @@
+
+
+
+
+
+
+netmiko.ubiquiti API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ubiquiti
+
+
+
+Source code
+from netmiko.ubiquiti.edge_ssh import UbiquitiEdgeSSH
+from netmiko.ubiquiti.edgerouter_ssh import UbiquitiEdgeRouterSSH
+from netmiko.ubiquiti.unifiswitch_ssh import UbiquitiUnifiSwitchSSH
+
+__all__ = [
+ "UbiquitiEdgeRouterSSH",
+ "UbiquitiEdgeSSH",
+ "UbiquitiUnifiSwitchSSH",
+]
+
+
+
+
+
+
+
+
+
+-
+
Implement methods for interacting with EdgeOS EdgeRouter network devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiEdgeRouterSSH(VyOSSSH):
+ """Implement methods for interacting with EdgeOS EdgeRouter network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
+
+Ancestors
+
+Methods
+
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
+
+
+
+Inherited members
+
+
+
+class UbiquitiEdgeSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Ubiquity EdgeSwitch devices.
+Mostly conforms to Cisco IOS style syntax with a few minor changes.
+This is NOT for EdgeRouter devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiEdgeSSH(CiscoSSHConnection):
+ """
+ Implements support for Ubiquity EdgeSwitch devices.
+
+ Mostly conforms to Cisco IOS style syntax with a few minor changes.
+
+ This is NOT for EdgeRouter devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+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: str = ")#", pattern: str = "") -> bool:
+ """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='', re_flags=0)
+
+-
+
Enter configuration mode.
+
+Source code
+def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='#.*')
+
+-
+
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+
+
+def save_config(self, cmd='write memory', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+
+Inherited members
+
+
+
+class UbiquitiUnifiSwitchSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Ubiquity EdgeSwitch devices.
+Mostly conforms to Cisco IOS style syntax with a few minor changes.
+This is NOT for EdgeRouter devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiUnifiSwitchSSH(UbiquitiEdgeSSH):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Gracefully exit the SSH session."""
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+
+ # Exit from the first 'telnet localhost'
+ self.write_channel(command + self.RETURN)
+ except Exception:
+ pass
+
+ super().cleanup()
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+When SSHing to a UniFi switch, the session initially starts at a Linux
+shell. Nothing interesting can be done in this environment, however,
+running telnet localhost drops the session to a more familiar
+environment.
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/unifiswitch_ssh.html b/docs/netmiko/ubiquiti/unifiswitch_ssh.html
new file mode 100644
index 000000000..13ea4fe67
--- /dev/null
+++ b/docs/netmiko/ubiquiti/unifiswitch_ssh.html
@@ -0,0 +1,351 @@
+
+
+
+
+
+
+netmiko.ubiquiti.unifiswitch_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.ubiquiti.unifiswitch_ssh
+
+
+
+Source code
+import time
+from netmiko.ubiquiti.edge_ssh import UbiquitiEdgeSSH
+
+
+class UbiquitiUnifiSwitchSSH(UbiquitiEdgeSSH):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Gracefully exit the SSH session."""
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+
+ # Exit from the first 'telnet localhost'
+ self.write_channel(command + self.RETURN)
+ except Exception:
+ pass
+
+ super().cleanup()
+
+
+
+
+
+
+
+
+
+class UbiquitiUnifiSwitchSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements support for Ubiquity EdgeSwitch devices.
+Mostly conforms to Cisco IOS style syntax with a few minor changes.
+This is NOT for EdgeRouter devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class UbiquitiUnifiSwitchSSH(UbiquitiEdgeSSH):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Gracefully exit the SSH session."""
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+
+ # Exit from the first 'telnet localhost'
+ self.write_channel(command + self.RETURN)
+ except Exception:
+ pass
+
+ super().cleanup()
+
+Ancestors
+
+Methods
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+When SSHing to a UniFi switch, the session initially starts at a Linux
+shell. Nothing interesting can be done in this environment, however,
+running telnet localhost drops the session to a more familiar
+environment.
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/utilities.html b/docs/netmiko/utilities.html
new file mode 100644
index 000000000..e70f045b6
--- /dev/null
+++ b/docs/netmiko/utilities.html
@@ -0,0 +1,1501 @@
+
+
+
+
+
+
+netmiko.utilities API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.utilities
+
+
+Miscellaneous utility functions.
+
+Source code
+"""Miscellaneous utility functions."""
+from typing import (
+ Any,
+ AnyStr,
+ TypeVar,
+ Callable,
+ cast,
+ Optional,
+ Union,
+ List,
+ Dict,
+ Tuple,
+)
+from typing import TYPE_CHECKING
+from glob import glob
+import sys
+import io
+import os
+from pathlib import Path
+import functools
+from datetime import datetime
+from textfsm import clitable
+from textfsm.clitable import CliTableError
+from netmiko import log
+
+# For decorators
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+ from os import PathLike
+
+try:
+ from ttp import ttp
+
+ TTP_INSTALLED = True
+
+except ImportError:
+ TTP_INSTALLED = False
+
+try:
+ from genie.conf.base import Device
+ from genie.libs.parser.utils import get_parser
+ from pyats.datastructures import AttrDict
+
+ GENIE_INSTALLED = True
+except ImportError:
+ GENIE_INSTALLED = False
+
+# If we are on python < 3.7, we need to force the import of importlib.resources backport
+if sys.version_info[:2] >= (3, 7):
+ import importlib.resources as pkg_resources
+else:
+ import importlib_resources as pkg_resources
+
+try:
+ import serial.tools.list_ports
+
+ PYSERIAL_INSTALLED = True
+except ImportError:
+ PYSERIAL_INSTALLED = False
+
+# 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",
+ "extreme_ers": "show running-config",
+ "extreme_exos": "show configuration",
+ "extreme_netiron": "show running-config",
+ "extreme_nos": "show running-config",
+ "extreme_slx": "show running-config",
+ "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",
+ "checkpoint": "show configuration",
+ "cisco_wlc": "show run-config",
+ "enterasys": "show running-config",
+ "dell_force10": "show running-config",
+ "avaya_vsp": "show running-config",
+ "avaya_ers": "show running-config",
+ "brocade_vdx": "show running-config",
+ "brocade_nos": "show running-config",
+ "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
+new_dict = {}
+for k, v in SHOW_RUN_MAPPER.items():
+ new_key = k + "_ssh"
+ new_dict[k] = v
+ new_dict[new_key] = v
+SHOW_RUN_MAPPER = new_dict
+
+# Default location of netmiko temp directory for netmiko tools
+NETMIKO_BASE_DIR = "~/.netmiko"
+
+
+def load_yaml_file(yaml_file: Union[str, bytes, "PathLike[Any]"]) -> Any:
+ """Read YAML file."""
+ try:
+ import yaml
+ except ImportError:
+ sys.exit("Unable to import yaml module.")
+ try:
+ with io.open(yaml_file, "rt", encoding="utf-8") as fname:
+ return yaml.safe_load(fname)
+ except IOError:
+ sys.exit("Unable to open YAML file")
+
+
+def load_devices(file_name: Union[str, bytes, "PathLike[Any]", None] = None) -> Any:
+ """Find and load .netmiko.yml file."""
+ yaml_devices_file = find_cfg_file(file_name)
+ return load_yaml_file(yaml_devices_file)
+
+
+def find_cfg_file(
+ file_name: Union[str, bytes, "PathLike[Any]", None] = None
+) -> Union[str, bytes, "PathLike[Any]"]:
+ """
+ Search for netmiko_tools inventory file in the following order:
+ NETMIKO_TOOLS_CFG environment variable
+ Current directory
+ Home directory
+ Look for file named: .netmiko.yml or netmiko.yml
+ Also allow NETMIKO_TOOLS_CFG to point directly at a file
+ """
+ if file_name and os.path.isfile(file_name):
+ return file_name
+ optional_path = os.environ.get("NETMIKO_TOOLS_CFG", "")
+ if os.path.isfile(optional_path):
+ return optional_path
+ search_paths = [optional_path, ".", os.path.expanduser("~")]
+ # Filter optional_path if null
+ search_paths = [path for path in search_paths if path]
+ for path in search_paths:
+ files = glob(f"{path}/.netmiko.yml") + glob(f"{path}/netmiko.yml")
+ if files:
+ return files[0]
+ raise IOError(
+ ".netmiko.yml file not found in NETMIKO_TOOLS environment variable directory,"
+ " current directory, or home directory."
+ )
+
+
+def display_inventory(my_devices: Dict[str, Union[List[str], Dict[str, Any]]]) -> None:
+ """Print out inventory devices and groups."""
+ inventory_groups = ["all"]
+ inventory_devices = []
+ for k, v in my_devices.items():
+ if isinstance(v, list):
+ inventory_groups.append(k)
+ elif isinstance(v, dict):
+ inventory_devices.append((k, v["device_type"]))
+
+ inventory_groups.sort()
+ inventory_devices.sort(key=lambda x: x[0])
+ print("\nDevices:")
+ print("-" * 40)
+ for a_device, device_type in inventory_devices:
+ device_type = f" ({device_type})"
+ print(f"{a_device:<25}{device_type:>15}")
+ print("\n\nGroups:")
+ print("-" * 40)
+ for a_group in inventory_groups:
+ print(a_group)
+ print()
+
+
+def obtain_all_devices(
+ my_devices: Dict[str, Union[List[str], Dict[str, Any]]]
+) -> Dict[str, Dict[str, Any]]:
+ """Dynamically create 'all' group."""
+ new_devices = {}
+ for device_name, device_or_group in my_devices.items():
+ # Skip any groups
+ if not isinstance(device_or_group, list):
+ new_devices[device_name] = device_or_group
+ return new_devices
+
+
+def obtain_netmiko_filename(device_name: str) -> str:
+ """Create file name based on device_name."""
+ _, netmiko_full_dir = find_netmiko_dir()
+ return f"{netmiko_full_dir}/{device_name}.txt"
+
+
+def write_tmp_file(device_name: str, output: str) -> str:
+ file_name = obtain_netmiko_filename(device_name)
+ with open(file_name, "w") as f:
+ f.write(output)
+ return file_name
+
+
+def ensure_dir_exists(verify_dir: str) -> None:
+ """Ensure directory exists. Create if necessary."""
+ if not os.path.exists(verify_dir):
+ # Doesn't exist create dir
+ os.makedirs(verify_dir)
+ else:
+ # Exists
+ if not os.path.isdir(verify_dir):
+ # Not a dir, raise an exception
+ raise ValueError(f"{verify_dir} is not a directory")
+
+
+def find_netmiko_dir() -> Tuple[str, str]:
+ """Check environment first, then default dir"""
+ try:
+ netmiko_base_dir = os.environ["NETMIKO_DIR"]
+ except KeyError:
+ netmiko_base_dir = NETMIKO_BASE_DIR
+ netmiko_base_dir = os.path.expanduser(netmiko_base_dir)
+ if netmiko_base_dir == "/":
+ raise ValueError("/ cannot be netmiko_base_dir")
+ netmiko_full_dir = f"{netmiko_base_dir}/tmp"
+ return (netmiko_base_dir, netmiko_full_dir)
+
+
+def write_bytes(out_data: AnyStr, encoding: str = "ascii") -> bytes:
+ """Legacy for Python2 and Python3 compatible byte stream."""
+ if sys.version_info[0] >= 3:
+ if isinstance(out_data, str):
+ if encoding == "utf-8":
+ return out_data.encode("utf-8")
+ else:
+ return out_data.encode("ascii", "ignore")
+ elif isinstance(out_data, bytes):
+ return out_data
+ msg = f"Invalid value for out_data neither unicode nor byte string: {str(out_data)}"
+ raise ValueError(msg)
+
+
+def check_serial_port(name: str) -> str:
+ """returns valid COM Port."""
+
+ if not PYSERIAL_INSTALLED:
+ msg = (
+ "\npyserial is not installed. Please PIP install pyserial:\n\n"
+ "pip install pyserial\n\n"
+ )
+ raise ValueError(msg)
+
+ try:
+ cdc = next(serial.tools.list_ports.grep(name))
+ serial_port = cdc[0]
+ assert isinstance(serial_port, str)
+ return serial_port
+ except StopIteration:
+ msg = f"device {name} not found. "
+ msg += "available devices are: "
+ ports = list(serial.tools.list_ports.comports())
+ for p in ports:
+ msg += f"{str(p)},"
+ raise ValueError(msg)
+
+
+def get_template_dir(_skip_ntc_package: bool = False) -> str:
+ """
+ Find and return the directory containing the TextFSM index file.
+
+ Order of preference is:
+ 1) Find directory in `NET_TEXTFSM` Environment Variable.
+ 2) Check for pip installed `ntc-templates` location in this environment.
+ 3) ~/ntc-templates/ntc_templates/templates.
+
+ If `index` file is not found in any of these locations, raise ValueError
+
+ :return: directory containing the TextFSM index file
+
+ """
+
+ msg = """
+Directory containing TextFSM index file not found.
+
+Please set the NET_TEXTFSM environment variable to point at the directory containing your TextFSM
+index file.
+
+Alternatively, `pip install ntc-templates` (if using ntc-templates).
+
+"""
+
+ # Try NET_TEXTFSM environment variable
+ template_dir = os.environ.get("NET_TEXTFSM")
+ if template_dir is not None:
+ template_dir = os.path.expanduser(template_dir)
+ index = os.path.join(template_dir, "index")
+ if not os.path.isfile(index):
+ # Assume only base ./ntc-templates specified
+ template_dir = os.path.join(template_dir, "templates")
+
+ else:
+ # Try 'pip installed' ntc-templates
+ try:
+ with pkg_resources.path(
+ package="ntc_templates", resource="parse.py"
+ ) as posix_path:
+ # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
+ template_dir = str(posix_path.parent.joinpath("templates"))
+ # This is for Netmiko automated testing
+ if _skip_ntc_package:
+ raise ModuleNotFoundError()
+
+ except ModuleNotFoundError:
+ # Finally check in ~/ntc-templates/ntc_templates/templates
+ home_dir = os.path.expanduser("~")
+ template_dir = os.path.join(
+ home_dir, "ntc-templates", "ntc_templates", "templates"
+ )
+
+ index = os.path.join(template_dir, "index")
+ if not os.path.isdir(template_dir) or not os.path.isfile(index):
+ raise ValueError(msg)
+ return os.path.abspath(template_dir)
+
+
+def clitable_to_dict(cli_table: clitable.CliTable) -> List[Dict[str, str]]:
+ """Converts TextFSM cli_table object to list of dictionaries."""
+ return_list = []
+ for row in cli_table:
+ temp_dict = {}
+ for index, element in enumerate(row):
+ temp_dict[cli_table.header[index].lower()] = element
+ return_list.append(temp_dict)
+ return return_list
+
+
+def _textfsm_parse(
+ textfsm_obj: clitable.CliTable,
+ raw_output: str,
+ attrs: Dict[str, str],
+ template_file: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """Perform the actual TextFSM parsing using the CliTable object."""
+ tfsm_parse: Callable[..., Any] = textfsm_obj.ParseCmd
+ try:
+ # Parse output through template
+ if template_file is not None:
+ tfsm_parse(raw_output, templates=template_file)
+ else:
+ tfsm_parse(raw_output, attrs)
+
+ structured_data = clitable_to_dict(textfsm_obj)
+ if structured_data == []:
+ return raw_output
+ else:
+ return structured_data
+ except (FileNotFoundError, CliTableError):
+ return raw_output
+
+
+def get_structured_data_textfsm(
+ raw_output: str,
+ platform: Optional[str] = None,
+ command: Optional[str] = None,
+ template: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """
+ Convert raw CLI output to structured data using TextFSM template.
+
+ You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+ then you must use an CliTable index file.
+ """
+ if platform is None or command is None:
+ attrs = {}
+ else:
+ attrs = {"Command": command, "Platform": platform}
+
+ if template is None:
+ if attrs == {}:
+ raise ValueError(
+ "Either 'platform/command' or 'template' must be specified."
+ )
+ template_dir = get_template_dir()
+ index_file = os.path.join(template_dir, "index")
+ textfsm_obj = clitable.CliTable(index_file, template_dir)
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+
+ # Retry the output if "cisco_xe" and not structured data
+ if platform and "cisco_xe" in platform:
+ if not isinstance(output, list):
+ attrs["Platform"] = "cisco_ios"
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+ return output
+ else:
+ template_path = Path(os.path.expanduser(template))
+ template_file = template_path.name
+ template_dir_alt = template_path.parents[0]
+ # CliTable with no index will fall-back to a TextFSM parsing behavior
+ textfsm_obj = clitable.CliTable(template_dir=template_dir_alt)
+ return _textfsm_parse(
+ textfsm_obj, raw_output, attrs, template_file=template_file
+ )
+
+
+# For compatibility
+get_structured_data = get_structured_data_textfsm
+
+
+def get_structured_data_ttp(raw_output: str, template: str) -> Union[str, List[Any]]:
+ """
+ Convert raw CLI output to structured data using TTP template.
+
+ You can use a straight TextFSM file i.e. specify "template"
+ """
+ if not TTP_INSTALLED:
+ msg = "\nTTP is not installed. Please PIP install ttp:\n\npip install ttp\n"
+ raise ValueError(msg)
+
+ try:
+ ttp_parser = ttp(data=raw_output, template=template)
+ ttp_parser.parse(one=True)
+ result: List[Any] = ttp_parser.result(format="raw")
+ return result
+ except Exception:
+ return raw_output
+
+
+def run_ttp_template(
+ connection: "BaseConnection",
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Dict[str, Any],
+ **kwargs: Any,
+) -> Any:
+ """
+ Helper function to run TTP template parsing.
+
+ :param connection: Netmiko connection object
+
+ :param template: TTP template
+
+ :param res_kwargs: ``**res_kwargs`` arguments for TTP result method
+
+ :param kwargs: ``**kwargs`` for TTP object instantiation
+ """
+ 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
+ out_list = [
+ getattr(connection, method)(command_string=command, **method_kwargs)
+ for command in commands
+ ]
+ output = "\n".join(out_list)
+
+ # 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: str, platform: str, command: str
+) -> Union[str, Dict[str, Any]]:
+ if not sys.version_info >= (3, 4):
+ raise ValueError("Genie requires Python >= 3.4")
+
+ if not GENIE_INSTALLED:
+ msg = (
+ "\nGenie and PyATS are not installed. Please PIP install both Genie and PyATS:\n"
+ "pip install genie\npip install pyats\n"
+ )
+ raise ValueError(msg)
+
+ if "cisco" not in platform:
+ return raw_output
+
+ genie_device_mapper = {
+ "cisco_ios": "ios",
+ "cisco_xe": "iosxe",
+ "cisco_xr": "iosxr",
+ "cisco_nxos": "nxos",
+ "cisco_asa": "asa",
+ }
+
+ os = None
+ # platform might be _ssh, _telnet, _serial strip that off
+ if platform.count("_") > 1:
+ base_list = platform.split("_")[:-1]
+ base_platform = "_".join(base_list)
+ else:
+ base_platform = platform
+
+ os = genie_device_mapper.get(base_platform)
+ if os is None:
+ return raw_output
+
+ # Genie specific construct for doing parsing (based on Genie in Ansible)
+ device = Device("new_device", os=os)
+ device.custom.setdefault("abstraction", {})
+ device.custom["abstraction"]["order"] = ["os"]
+ device.cli = AttrDict({"execute": None})
+ try:
+ # Test whether there is a parser for given command (return Exception if fails)
+ get_parser(command, device)
+ parsed_output: Dict[str, Any] = device.parse(command, output=raw_output)
+ return parsed_output
+ except Exception:
+ return raw_output
+
+
+def structured_data_converter(
+ raw_data: str,
+ command: str,
+ platform: str,
+ use_textfsm: bool = False,
+ use_ttp: bool = False,
+ use_genie: bool = False,
+ textfsm_template: Optional[str] = None,
+ ttp_template: Optional[str] = None,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Try structured data converters in the following order: TextFSM, TTP, Genie.
+
+ Return the first structured data found, else return the raw_data as-is.
+ """
+ command = command.strip()
+ if use_textfsm:
+ structured_output_tfsm = get_structured_data_textfsm(
+ raw_data, platform=platform, command=command, template=textfsm_template
+ )
+ if not isinstance(structured_output_tfsm, str):
+ return structured_output_tfsm
+
+ if use_ttp:
+ if ttp_template is None:
+ msg = """
+The argument 'ttp_template=/path/to/template.ttp' must be set when use_ttp=True
+"""
+ raise ValueError(msg)
+ else:
+ structured_output_ttp = get_structured_data_ttp(
+ raw_data, template=ttp_template
+ )
+
+ if not isinstance(structured_output_ttp, str):
+ return structured_output_ttp
+
+ if use_genie:
+ structured_output_genie = get_structured_data_genie(
+ raw_data, platform=platform, command=command
+ )
+ if not isinstance(structured_output_genie, str):
+ return structured_output_genie
+ return raw_data
+
+
+def select_cmd_verify(func: F) -> F:
+ """Override function cmd_verify argument with global setting."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ if self.global_cmd_verify is not None:
+ kwargs["cmd_verify"] = self.global_cmd_verify
+ return func(self, *args, **kwargs)
+
+ return cast(F, wrapper_decorator)
+
+
+def m_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: Any, *args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(self, *args, **kwargs)
+ end_time = datetime.now()
+ method_name = str(func)
+ print(f"{method_name}: Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+def f_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(*args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(*args, **kwargs)
+ end_time = datetime.now()
+ print(f"Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+def calc_old_timeout(
+ max_loops: Optional[int] = None,
+ delay_factor: Optional[float] = None,
+ loop_delay: float = 0.2,
+ old_timeout: int = 100,
+) -> float:
+ """
+ loop_delay is .2 in Netmiko 3.x
+ delay_factor would multiple the loop delay
+ Number of loops was typically 500
+
+ Thus each loop would sleep (loop_delay * delay_factor) seconds
+ That sleep would happen max_loops time
+
+ Formula is (loop_delay * delay_factor) * max_loops
+
+ There was a way Netmiko's self.timeout could override the default settings and essentially be
+ used to adjust max_loops (this was probably rarely used).
+ """
+ if max_loops is None:
+ max_loops = 500
+ if delay_factor is None:
+ delay_factor = 1.0
+ # This is the logic for having self.timeout override max_loops
+ if delay_factor == 1 and max_loops == 500:
+ max_loops = int(old_timeout / loop_delay)
+
+ return max_loops * loop_delay * delay_factor
+
+
+
+
+
+
+
+
+def calc_old_timeout(max_loops=None, delay_factor=None, loop_delay=0.2, old_timeout=100)
+
+-
+
loop_delay is .2 in Netmiko 3.x
+delay_factor would multiple the loop delay
+Number of loops was typically 500
+Thus each loop would sleep (loop_delay * delay_factor) seconds
+That sleep would happen max_loops time
+Formula is (loop_delay * delay_factor) * max_loops
+There was a way Netmiko's self.timeout could override the default settings and essentially be
+used to adjust max_loops (this was probably rarely used).
+
+Source code
+def calc_old_timeout(
+ max_loops: Optional[int] = None,
+ delay_factor: Optional[float] = None,
+ loop_delay: float = 0.2,
+ old_timeout: int = 100,
+) -> float:
+ """
+ loop_delay is .2 in Netmiko 3.x
+ delay_factor would multiple the loop delay
+ Number of loops was typically 500
+
+ Thus each loop would sleep (loop_delay * delay_factor) seconds
+ That sleep would happen max_loops time
+
+ Formula is (loop_delay * delay_factor) * max_loops
+
+ There was a way Netmiko's self.timeout could override the default settings and essentially be
+ used to adjust max_loops (this was probably rarely used).
+ """
+ if max_loops is None:
+ max_loops = 500
+ if delay_factor is None:
+ delay_factor = 1.0
+ # This is the logic for having self.timeout override max_loops
+ if delay_factor == 1 and max_loops == 500:
+ max_loops = int(old_timeout / loop_delay)
+
+ return max_loops * loop_delay * delay_factor
+
+
+
+def check_serial_port(name)
+
+-
+
+
+Source code
+def check_serial_port(name: str) -> str:
+ """returns valid COM Port."""
+
+ if not PYSERIAL_INSTALLED:
+ msg = (
+ "\npyserial is not installed. Please PIP install pyserial:\n\n"
+ "pip install pyserial\n\n"
+ )
+ raise ValueError(msg)
+
+ try:
+ cdc = next(serial.tools.list_ports.grep(name))
+ serial_port = cdc[0]
+ assert isinstance(serial_port, str)
+ return serial_port
+ except StopIteration:
+ msg = f"device {name} not found. "
+ msg += "available devices are: "
+ ports = list(serial.tools.list_ports.comports())
+ for p in ports:
+ msg += f"{str(p)},"
+ raise ValueError(msg)
+
+
+
+def clitable_to_dict(cli_table)
+
+-
+
Converts TextFSM cli_table object to list of dictionaries.
+
+Source code
+def clitable_to_dict(cli_table: clitable.CliTable) -> List[Dict[str, str]]:
+ """Converts TextFSM cli_table object to list of dictionaries."""
+ return_list = []
+ for row in cli_table:
+ temp_dict = {}
+ for index, element in enumerate(row):
+ temp_dict[cli_table.header[index].lower()] = element
+ return_list.append(temp_dict)
+ return return_list
+
+
+
+def display_inventory(my_devices)
+
+-
+
Print out inventory devices and groups.
+
+Source code
+def display_inventory(my_devices: Dict[str, Union[List[str], Dict[str, Any]]]) -> None:
+ """Print out inventory devices and groups."""
+ inventory_groups = ["all"]
+ inventory_devices = []
+ for k, v in my_devices.items():
+ if isinstance(v, list):
+ inventory_groups.append(k)
+ elif isinstance(v, dict):
+ inventory_devices.append((k, v["device_type"]))
+
+ inventory_groups.sort()
+ inventory_devices.sort(key=lambda x: x[0])
+ print("\nDevices:")
+ print("-" * 40)
+ for a_device, device_type in inventory_devices:
+ device_type = f" ({device_type})"
+ print(f"{a_device:<25}{device_type:>15}")
+ print("\n\nGroups:")
+ print("-" * 40)
+ for a_group in inventory_groups:
+ print(a_group)
+ print()
+
+
+
+def ensure_dir_exists(verify_dir)
+
+-
+
Ensure directory exists. Create if necessary.
+
+Source code
+def ensure_dir_exists(verify_dir: str) -> None:
+ """Ensure directory exists. Create if necessary."""
+ if not os.path.exists(verify_dir):
+ # Doesn't exist create dir
+ os.makedirs(verify_dir)
+ else:
+ # Exists
+ if not os.path.isdir(verify_dir):
+ # Not a dir, raise an exception
+ raise ValueError(f"{verify_dir} is not a directory")
+
+
+
+def f_exec_time(func)
+
+-
+
+
+Source code
+def f_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(*args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(*args, **kwargs)
+ end_time = datetime.now()
+ print(f"Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+
+def find_cfg_file(file_name=None)
+
+-
+
Search for netmiko_tools inventory file in the following order:
+NETMIKO_TOOLS_CFG environment variable
+Current directory
+Home directory
+Look for file named: .netmiko.yml or netmiko.yml
+Also allow NETMIKO_TOOLS_CFG to point directly at a file
+
+Source code
+def find_cfg_file(
+ file_name: Union[str, bytes, "PathLike[Any]", None] = None
+) -> Union[str, bytes, "PathLike[Any]"]:
+ """
+ Search for netmiko_tools inventory file in the following order:
+ NETMIKO_TOOLS_CFG environment variable
+ Current directory
+ Home directory
+ Look for file named: .netmiko.yml or netmiko.yml
+ Also allow NETMIKO_TOOLS_CFG to point directly at a file
+ """
+ if file_name and os.path.isfile(file_name):
+ return file_name
+ optional_path = os.environ.get("NETMIKO_TOOLS_CFG", "")
+ if os.path.isfile(optional_path):
+ return optional_path
+ search_paths = [optional_path, ".", os.path.expanduser("~")]
+ # Filter optional_path if null
+ search_paths = [path for path in search_paths if path]
+ for path in search_paths:
+ files = glob(f"{path}/.netmiko.yml") + glob(f"{path}/netmiko.yml")
+ if files:
+ return files[0]
+ raise IOError(
+ ".netmiko.yml file not found in NETMIKO_TOOLS environment variable directory,"
+ " current directory, or home directory."
+ )
+
+
+
+def find_netmiko_dir()
+
+-
+
Check environment first, then default dir
+
+Source code
+def find_netmiko_dir() -> Tuple[str, str]:
+ """Check environment first, then default dir"""
+ try:
+ netmiko_base_dir = os.environ["NETMIKO_DIR"]
+ except KeyError:
+ netmiko_base_dir = NETMIKO_BASE_DIR
+ netmiko_base_dir = os.path.expanduser(netmiko_base_dir)
+ if netmiko_base_dir == "/":
+ raise ValueError("/ cannot be netmiko_base_dir")
+ netmiko_full_dir = f"{netmiko_base_dir}/tmp"
+ return (netmiko_base_dir, netmiko_full_dir)
+
+
+
+def get_structured_data(raw_output, platform=None, command=None, template=None)
+
+-
+
Convert raw CLI output to structured data using TextFSM template.
+You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+then you must use an CliTable index file.
+
+Source code
+def get_structured_data_textfsm(
+ raw_output: str,
+ platform: Optional[str] = None,
+ command: Optional[str] = None,
+ template: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """
+ Convert raw CLI output to structured data using TextFSM template.
+
+ You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+ then you must use an CliTable index file.
+ """
+ if platform is None or command is None:
+ attrs = {}
+ else:
+ attrs = {"Command": command, "Platform": platform}
+
+ if template is None:
+ if attrs == {}:
+ raise ValueError(
+ "Either 'platform/command' or 'template' must be specified."
+ )
+ template_dir = get_template_dir()
+ index_file = os.path.join(template_dir, "index")
+ textfsm_obj = clitable.CliTable(index_file, template_dir)
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+
+ # Retry the output if "cisco_xe" and not structured data
+ if platform and "cisco_xe" in platform:
+ if not isinstance(output, list):
+ attrs["Platform"] = "cisco_ios"
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+ return output
+ else:
+ template_path = Path(os.path.expanduser(template))
+ template_file = template_path.name
+ template_dir_alt = template_path.parents[0]
+ # CliTable with no index will fall-back to a TextFSM parsing behavior
+ textfsm_obj = clitable.CliTable(template_dir=template_dir_alt)
+ return _textfsm_parse(
+ textfsm_obj, raw_output, attrs, template_file=template_file
+ )
+
+
+
+def get_structured_data_genie(raw_output, platform, command)
+
+-
+
+
+Source code
+def get_structured_data_genie(
+ raw_output: str, platform: str, command: str
+) -> Union[str, Dict[str, Any]]:
+ if not sys.version_info >= (3, 4):
+ raise ValueError("Genie requires Python >= 3.4")
+
+ if not GENIE_INSTALLED:
+ msg = (
+ "\nGenie and PyATS are not installed. Please PIP install both Genie and PyATS:\n"
+ "pip install genie\npip install pyats\n"
+ )
+ raise ValueError(msg)
+
+ if "cisco" not in platform:
+ return raw_output
+
+ genie_device_mapper = {
+ "cisco_ios": "ios",
+ "cisco_xe": "iosxe",
+ "cisco_xr": "iosxr",
+ "cisco_nxos": "nxos",
+ "cisco_asa": "asa",
+ }
+
+ os = None
+ # platform might be _ssh, _telnet, _serial strip that off
+ if platform.count("_") > 1:
+ base_list = platform.split("_")[:-1]
+ base_platform = "_".join(base_list)
+ else:
+ base_platform = platform
+
+ os = genie_device_mapper.get(base_platform)
+ if os is None:
+ return raw_output
+
+ # Genie specific construct for doing parsing (based on Genie in Ansible)
+ device = Device("new_device", os=os)
+ device.custom.setdefault("abstraction", {})
+ device.custom["abstraction"]["order"] = ["os"]
+ device.cli = AttrDict({"execute": None})
+ try:
+ # Test whether there is a parser for given command (return Exception if fails)
+ get_parser(command, device)
+ parsed_output: Dict[str, Any] = device.parse(command, output=raw_output)
+ return parsed_output
+ except Exception:
+ return raw_output
+
+
+
+def get_structured_data_textfsm(raw_output, platform=None, command=None, template=None)
+
+-
+
Convert raw CLI output to structured data using TextFSM template.
+You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+then you must use an CliTable index file.
+
+Source code
+def get_structured_data_textfsm(
+ raw_output: str,
+ platform: Optional[str] = None,
+ command: Optional[str] = None,
+ template: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """
+ Convert raw CLI output to structured data using TextFSM template.
+
+ You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+ then you must use an CliTable index file.
+ """
+ if platform is None or command is None:
+ attrs = {}
+ else:
+ attrs = {"Command": command, "Platform": platform}
+
+ if template is None:
+ if attrs == {}:
+ raise ValueError(
+ "Either 'platform/command' or 'template' must be specified."
+ )
+ template_dir = get_template_dir()
+ index_file = os.path.join(template_dir, "index")
+ textfsm_obj = clitable.CliTable(index_file, template_dir)
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+
+ # Retry the output if "cisco_xe" and not structured data
+ if platform and "cisco_xe" in platform:
+ if not isinstance(output, list):
+ attrs["Platform"] = "cisco_ios"
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+ return output
+ else:
+ template_path = Path(os.path.expanduser(template))
+ template_file = template_path.name
+ template_dir_alt = template_path.parents[0]
+ # CliTable with no index will fall-back to a TextFSM parsing behavior
+ textfsm_obj = clitable.CliTable(template_dir=template_dir_alt)
+ return _textfsm_parse(
+ textfsm_obj, raw_output, attrs, template_file=template_file
+ )
+
+
+
+def get_structured_data_ttp(raw_output, template)
+
+-
+
Convert raw CLI output to structured data using TTP template.
+You can use a straight TextFSM file i.e. specify "template"
+
+Source code
+def get_structured_data_ttp(raw_output: str, template: str) -> Union[str, List[Any]]:
+ """
+ Convert raw CLI output to structured data using TTP template.
+
+ You can use a straight TextFSM file i.e. specify "template"
+ """
+ if not TTP_INSTALLED:
+ msg = "\nTTP is not installed. Please PIP install ttp:\n\npip install ttp\n"
+ raise ValueError(msg)
+
+ try:
+ ttp_parser = ttp(data=raw_output, template=template)
+ ttp_parser.parse(one=True)
+ result: List[Any] = ttp_parser.result(format="raw")
+ return result
+ except Exception:
+ return raw_output
+
+
+
+def get_template_dir()
+
+-
+
Find and return the directory containing the TextFSM index file.
+Order of preference is:
+1) Find directory in NET_TEXTFSM Environment Variable.
+2) Check for pip installed ntc-templates location in this environment.
+3) ~/ntc-templates/ntc_templates/templates.
+If index file is not found in any of these locations, raise ValueError
+:return: directory containing the TextFSM index file
+
+Source code
+def get_template_dir(_skip_ntc_package: bool = False) -> str:
+ """
+ Find and return the directory containing the TextFSM index file.
+
+ Order of preference is:
+ 1) Find directory in `NET_TEXTFSM` Environment Variable.
+ 2) Check for pip installed `ntc-templates` location in this environment.
+ 3) ~/ntc-templates/ntc_templates/templates.
+
+ If `index` file is not found in any of these locations, raise ValueError
+
+ :return: directory containing the TextFSM index file
+
+ """
+
+ msg = """
+Directory containing TextFSM index file not found.
+
+Please set the NET_TEXTFSM environment variable to point at the directory containing your TextFSM
+index file.
+
+Alternatively, `pip install ntc-templates` (if using ntc-templates).
+
+"""
+
+ # Try NET_TEXTFSM environment variable
+ template_dir = os.environ.get("NET_TEXTFSM")
+ if template_dir is not None:
+ template_dir = os.path.expanduser(template_dir)
+ index = os.path.join(template_dir, "index")
+ if not os.path.isfile(index):
+ # Assume only base ./ntc-templates specified
+ template_dir = os.path.join(template_dir, "templates")
+
+ else:
+ # Try 'pip installed' ntc-templates
+ try:
+ with pkg_resources.path(
+ package="ntc_templates", resource="parse.py"
+ ) as posix_path:
+ # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
+ template_dir = str(posix_path.parent.joinpath("templates"))
+ # This is for Netmiko automated testing
+ if _skip_ntc_package:
+ raise ModuleNotFoundError()
+
+ except ModuleNotFoundError:
+ # Finally check in ~/ntc-templates/ntc_templates/templates
+ home_dir = os.path.expanduser("~")
+ template_dir = os.path.join(
+ home_dir, "ntc-templates", "ntc_templates", "templates"
+ )
+
+ index = os.path.join(template_dir, "index")
+ if not os.path.isdir(template_dir) or not os.path.isfile(index):
+ raise ValueError(msg)
+ return os.path.abspath(template_dir)
+
+
+
+def load_devices(file_name=None)
+
+-
+
Find and load .netmiko.yml file.
+
+Source code
+def load_devices(file_name: Union[str, bytes, "PathLike[Any]", None] = None) -> Any:
+ """Find and load .netmiko.yml file."""
+ yaml_devices_file = find_cfg_file(file_name)
+ return load_yaml_file(yaml_devices_file)
+
+
+
+def load_yaml_file(yaml_file)
+
+-
+
+
+Source code
+def load_yaml_file(yaml_file: Union[str, bytes, "PathLike[Any]"]) -> Any:
+ """Read YAML file."""
+ try:
+ import yaml
+ except ImportError:
+ sys.exit("Unable to import yaml module.")
+ try:
+ with io.open(yaml_file, "rt", encoding="utf-8") as fname:
+ return yaml.safe_load(fname)
+ except IOError:
+ sys.exit("Unable to open YAML file")
+
+
+
+def m_exec_time(func)
+
+-
+
+
+Source code
+def m_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: Any, *args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(self, *args, **kwargs)
+ end_time = datetime.now()
+ method_name = str(func)
+ print(f"{method_name}: Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+
+def obtain_all_devices(my_devices)
+
+-
+
Dynamically create 'all' group.
+
+Source code
+def obtain_all_devices(
+ my_devices: Dict[str, Union[List[str], Dict[str, Any]]]
+) -> Dict[str, Dict[str, Any]]:
+ """Dynamically create 'all' group."""
+ new_devices = {}
+ for device_name, device_or_group in my_devices.items():
+ # Skip any groups
+ if not isinstance(device_or_group, list):
+ new_devices[device_name] = device_or_group
+ return new_devices
+
+
+
+def obtain_netmiko_filename(device_name)
+
+-
+
Create file name based on device_name.
+
+Source code
+def obtain_netmiko_filename(device_name: str) -> str:
+ """Create file name based on device_name."""
+ _, netmiko_full_dir = find_netmiko_dir()
+ 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
+:param template: TTP template
+:param res_kwargs: **res_kwargs arguments for TTP result method
+:param kwargs: **kwargs for TTP object instantiation
+
+Source code
+def run_ttp_template(
+ connection: "BaseConnection",
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Dict[str, Any],
+ **kwargs: Any,
+) -> Any:
+ """
+ Helper function to run TTP template parsing.
+
+ :param connection: Netmiko connection object
+
+ :param template: TTP template
+
+ :param res_kwargs: ``**res_kwargs`` arguments for TTP result method
+
+ :param kwargs: ``**kwargs`` for TTP object instantiation
+ """
+ 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
+ out_list = [
+ getattr(connection, method)(command_string=command, **method_kwargs)
+ for command in commands
+ ]
+ output = "\n".join(out_list)
+
+ # 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)
+
+-
+
Override function cmd_verify argument with global setting.
+
+Source code
+def select_cmd_verify(func: F) -> F:
+ """Override function cmd_verify argument with global setting."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ if self.global_cmd_verify is not None:
+ kwargs["cmd_verify"] = self.global_cmd_verify
+ return func(self, *args, **kwargs)
+
+ return cast(F, wrapper_decorator)
+
+
+
+def structured_data_converter(raw_data, command, platform, use_textfsm=False, use_ttp=False, use_genie=False, textfsm_template=None, ttp_template=None)
+
+-
+
Try structured data converters in the following order: TextFSM, TTP, Genie.
+Return the first structured data found, else return the raw_data as-is.
+
+Source code
+def structured_data_converter(
+ raw_data: str,
+ command: str,
+ platform: str,
+ use_textfsm: bool = False,
+ use_ttp: bool = False,
+ use_genie: bool = False,
+ textfsm_template: Optional[str] = None,
+ ttp_template: Optional[str] = None,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Try structured data converters in the following order: TextFSM, TTP, Genie.
+
+ Return the first structured data found, else return the raw_data as-is.
+ """
+ command = command.strip()
+ if use_textfsm:
+ structured_output_tfsm = get_structured_data_textfsm(
+ raw_data, platform=platform, command=command, template=textfsm_template
+ )
+ if not isinstance(structured_output_tfsm, str):
+ return structured_output_tfsm
+
+ if use_ttp:
+ if ttp_template is None:
+ msg = """
+The argument 'ttp_template=/path/to/template.ttp' must be set when use_ttp=True
+"""
+ raise ValueError(msg)
+ else:
+ structured_output_ttp = get_structured_data_ttp(
+ raw_data, template=ttp_template
+ )
+
+ if not isinstance(structured_output_ttp, str):
+ return structured_output_ttp
+
+ if use_genie:
+ structured_output_genie = get_structured_data_genie(
+ raw_data, platform=platform, command=command
+ )
+ if not isinstance(structured_output_genie, str):
+ return structured_output_genie
+ return raw_data
+
+
+
+def write_bytes(out_data, encoding='ascii')
+
+-
+
Legacy for Python2 and Python3 compatible byte stream.
+
+Source code
+def write_bytes(out_data: AnyStr, encoding: str = "ascii") -> bytes:
+ """Legacy for Python2 and Python3 compatible byte stream."""
+ if sys.version_info[0] >= 3:
+ if isinstance(out_data, str):
+ if encoding == "utf-8":
+ return out_data.encode("utf-8")
+ else:
+ return out_data.encode("ascii", "ignore")
+ elif isinstance(out_data, bytes):
+ return out_data
+ msg = f"Invalid value for out_data neither unicode nor byte string: {str(out_data)}"
+ raise ValueError(msg)
+
+
+
+def write_tmp_file(device_name, output)
+
+-
+
+
+Source code
+def write_tmp_file(device_name: str, output: str) -> str:
+ file_name = obtain_netmiko_filename(device_name)
+ with open(file_name, "w") as f:
+ f.write(output)
+ return file_name
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/vyos/index.html b/docs/netmiko/vyos/index.html
new file mode 100644
index 000000000..c8acadf6d
--- /dev/null
+++ b/docs/netmiko/vyos/index.html
@@ -0,0 +1,571 @@
+
+
+
+
+
+
+netmiko.vyos API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.vyos.vyos_ssh import VyOSSSH
+
+__all__ = ["VyOSSSH"]
+
+
+
+
+
+
+
+
+
+class VyOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with VyOS network devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class VyOSSSH(NoEnable, CiscoSSHConnection):
+ """Implement methods for interacting with VyOS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
+ self.disable_paging(command="set terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\[edit\]",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+ ) -> str:
+ """Exit configuration mode"""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # Set prompt to user@hostname (remove two additional characters)
+ self.base_prompt = prompt[:-2].strip()
+ return self.base_prompt
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """Remain in configuration mode."""
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Checks if the device is in configuration mode
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='exit')
+
+-
+
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+) -> str:
+ """Exit configuration mode"""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs)
+
+-
+
Remain in configuration mode.
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """Remain in 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
+ self.disable_paging(command="set terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # Set prompt to user@hostname (remove two additional characters)
+ self.base_prompt = prompt[:-2].strip()
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/vyos/vyos_ssh.html b/docs/netmiko/vyos/vyos_ssh.html
new file mode 100644
index 000000000..c7a3b4491
--- /dev/null
+++ b/docs/netmiko/vyos/vyos_ssh.html
@@ -0,0 +1,696 @@
+
+
+
+
+
+
+netmiko.vyos.vyos_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.vyos.vyos_ssh
+
+
+
+Source code
+from typing import Optional, Union, Sequence, TextIO, Any
+import time
+import warnings
+import re
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class VyOSSSH(NoEnable, CiscoSSHConnection):
+ """Implement methods for interacting with VyOS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
+ self.disable_paging(command="set terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\[edit\]",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+ ) -> str:
+ """Exit configuration mode"""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # Set prompt to user@hostname (remove two additional characters)
+ self.base_prompt = prompt[:-2].strip()
+ return self.base_prompt
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """Remain in configuration mode."""
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+
+
+
+
+
+
+class VyOSSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implement methods for interacting with VyOS network devices.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class VyOSSSH(NoEnable, CiscoSSHConnection):
+ """Implement methods for interacting with VyOS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
+ self.disable_paging(command="set terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\[edit\]",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+ ) -> str:
+ """Exit configuration mode"""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # Set prompt to user@hostname (remove two additional characters)
+ self.base_prompt = prompt[:-2].strip()
+ return self.base_prompt
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """Remain in configuration mode."""
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Checks if the device is in configuration mode
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def commit(self, comment='', read_timeout=120.0, delay_factor=None)
+
+-
+
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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+Source code
+def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='exit')
+
+-
+
+
+Source code
+def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+) -> str:
+ """Exit configuration mode"""
+ output = ""
+ if self.check_config_mode():
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+
+
+def save_config(self, cmd='copy running-config startup-config', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs)
+
+-
+
Remain in configuration mode.
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+) -> str:
+ """Remain in 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
+ self.disable_paging(command="set terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#', delay_factor=1.0, pattern=None)
+
+-
+
Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output.
+
+Source code
+def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # Set prompt to user@hostname (remove two additional characters)
+ self.base_prompt = prompt[:-2].strip()
+ return self.base_prompt
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/watchguard/fireware_ssh.html b/docs/netmiko/watchguard/fireware_ssh.html
new file mode 100644
index 000000000..8546dea8f
--- /dev/null
+++ b/docs/netmiko/watchguard/fireware_ssh.html
@@ -0,0 +1,361 @@
+
+
+
+
+
+
+netmiko.watchguard.fireware_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.watchguard.fireware_ssh
+
+
+
+Source code
+import time
+from typing import Any
+
+from netmiko.base_connection import BaseConnection
+
+
+class WatchguardFirewareSSH(BaseConnection):
+ """
+ Implements methods for communicating with Watchguard Firebox firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ 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_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "configure", pattern: str = r"\#", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
+
+
+
+
+
+
+
+
+
+class WatchguardFirewareSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements methods for communicating with Watchguard Firebox firewalls.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class WatchguardFirewareSSH(BaseConnection):
+ """
+ Implements methods for communicating with Watchguard Firebox firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ 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_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "configure", pattern: str = r"\#", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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, *args, **kwargs)
+
+-
+
No save config on Watchguard.
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+Set the base prompt for interaction ('#').
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/watchguard/index.html b/docs/netmiko/watchguard/index.html
new file mode 100644
index 000000000..083667d98
--- /dev/null
+++ b/docs/netmiko/watchguard/index.html
@@ -0,0 +1,334 @@
+
+
+
+
+
+
+netmiko.watchguard API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.watchguard
+
+
+
+Source code
+from netmiko.watchguard.fireware_ssh import WatchguardFirewareSSH
+
+__all__ = ["WatchguardFirewareSSH"]
+
+
+
+
+
+
+
+
+
+class WatchguardFirewareSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Implements methods for communicating with Watchguard Firebox firewalls.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class WatchguardFirewareSSH(BaseConnection):
+ """
+ Implements methods for communicating with Watchguard Firebox firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ 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_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "configure", pattern: str = r"\#", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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, *args, **kwargs)
+
+-
+
No save config on Watchguard.
+
+Source code
+def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+Set the base prompt for interaction ('#').
+
+Source code
+def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/yamaha/index.html b/docs/netmiko/yamaha/index.html
new file mode 100644
index 000000000..e491543f5
--- /dev/null
+++ b/docs/netmiko/yamaha/index.html
@@ -0,0 +1,428 @@
+
+
+
+
+
+
+netmiko.yamaha API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from __future__ import unicode_literals
+from netmiko.yamaha.yamaha import YamahaSSH, YamahaTelnet
+
+__all__ = ["YamahaSSH", "YamahaTelnet"]
+
+
+
+
+
+
+
+
+
+class YamahaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Yamaha SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class YamahaSSH(YamahaBase):
+ """Yamaha SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class YamahaTelnet
+(*args, **kwargs)
+
+-
+
Yamaha Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class YamahaTelnet(YamahaBase):
+ """Yamaha Telnet driver."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/yamaha/yamaha.html b/docs/netmiko/yamaha/yamaha.html
new file mode 100644
index 000000000..44db311aa
--- /dev/null
+++ b/docs/netmiko/yamaha/yamaha.html
@@ -0,0 +1,840 @@
+
+
+
+
+
+
+netmiko.yamaha.yamaha API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.yamaha.yamaha
+
+
+
+Source code
+import time
+import re
+from typing import Any, Optional
+
+from netmiko.base_connection import BaseConnection
+
+
+class YamahaBase(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="console lines infinity")
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "administrator",
+ pattern: str = r"Password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """
+ When any changes have been made, the prompt 'Save new configuration ? (Y/N)'
+ appears before exiting. Ignore this by entering 'N'.
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(1)
+ output = self.read_channel()
+ if "(Y/N)" in output:
+ self.write_channel("N")
+ if self.base_prompt not in output:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in administrator mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "administrator",
+ pattern: str = "Password",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = ">") -> str:
+ """
+ No action taken. Call 'exit_enable_mode()' to explicitly exit Administration
+ Level.
+ """
+ return ""
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("Yamaha does not support save_config confirmation.")
+ self.enable()
+ # Some devices are slow so match on trailing-prompt if you can
+ return self._send_command_str(command_string=cmd)
+
+
+class YamahaSSH(YamahaBase):
+ """Yamaha SSH driver."""
+
+ pass
+
+
+class YamahaTelnet(YamahaBase):
+ """Yamaha Telnet driver."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class YamahaBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class YamahaBase(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="console lines infinity")
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "administrator",
+ pattern: str = r"Password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """
+ When any changes have been made, the prompt 'Save new configuration ? (Y/N)'
+ appears before exiting. Ignore this by entering 'N'.
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(1)
+ output = self.read_channel()
+ if "(Y/N)" in output:
+ self.write_channel("N")
+ if self.base_prompt not in output:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in administrator mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "administrator",
+ pattern: str = "Password",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = ">") -> str:
+ """
+ No action taken. Call 'exit_enable_mode()' to explicitly exit Administration
+ Level.
+ """
+ return ""
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("Yamaha does not support save_config confirmation.")
+ self.enable()
+ # Some devices are slow so match on trailing-prompt if you can
+ return self._send_command_str(command_string=cmd)
+
+Ancestors
+
+Subclasses
+
+Methods
+
+
+def check_config_mode(self, check_string='#', pattern='')
+
+-
+
Checks if the device is in administrator mode or not.
+
+Source code
+def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in administrator mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+
+
+def exit_config_mode(self, exit_config='exit', pattern='>')
+
+-
+
No action taken. Call 'exit_enable_mode()' to explicitly exit Administration
+Level.
+
+Source code
+def exit_config_mode(self, exit_config: str = "exit", pattern: str = ">") -> str:
+ """
+ No action taken. Call 'exit_enable_mode()' to explicitly exit Administration
+ Level.
+ """
+ return ""
+
+
+
+def exit_enable_mode(self, exit_command='exit')
+
+-
+
When any changes have been made, the prompt 'Save new configuration ? (Y/N)'
+appears before exiting. Ignore this by entering 'N'.
+
+Source code
+def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """
+ When any changes have been made, the prompt 'Save new configuration ? (Y/N)'
+ appears before exiting. Ignore this by entering 'N'.
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(1)
+ output = self.read_channel()
+ if "(Y/N)" in output:
+ self.write_channel("N")
+ if self.base_prompt not in output:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+
+
+def save_config(self, cmd='save', confirm=False, confirm_response='')
+
+-
+
+
+Source code
+def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("Yamaha does not support save_config confirmation.")
+ self.enable()
+ # Some devices are slow so match on trailing-prompt if you can
+ return self._send_command_str(command_string=cmd)
+
+
+
+def session_preparation(self)
+
+-
+
Prepare the session after the connection has been established.
+
+Source code
+def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="console lines infinity")
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class YamahaSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Yamaha SSH driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class YamahaSSH(YamahaBase):
+ """Yamaha SSH driver."""
+
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class YamahaTelnet
+(*args, **kwargs)
+
+-
+
Yamaha Telnet driver.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class YamahaTelnet(YamahaBase):
+ """Yamaha Telnet driver."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/zte/index.html b/docs/netmiko/zte/index.html
new file mode 100644
index 000000000..737071577
--- /dev/null
+++ b/docs/netmiko/zte/index.html
@@ -0,0 +1,448 @@
+
+
+
+
+
+
+netmiko.zte API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.zte.zte_zxros import ZteZxrosSSH
+from netmiko.zte.zte_zxros import ZteZxrosTelnet
+
+__all__ = ["ZteZxrosSSH", "ZteZxrosTelnet"]
+
+
+
+
+
+
+
+
+
+class ZteZxrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZteZxrosSSH(ZteZxrosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ZteZxrosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZteZxrosTelnet(ZteZxrosBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ ZTE need manually reply DO ECHO to enable echo command.
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Height:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/zte/zte_zxros.html b/docs/netmiko/zte/zte_zxros.html
new file mode 100644
index 000000000..30039d1b7
--- /dev/null
+++ b/docs/netmiko/zte/zte_zxros.html
@@ -0,0 +1,745 @@
+
+
+
+
+
+
+netmiko.zte.zte_zxros API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.zte.zte_zxros
+
+
+
+Source code
+import time
+from socket import socket
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, ECHO, SGA, NAWS, Telnet
+
+
+class ZteZxrosBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class ZteZxrosSSH(ZteZxrosBase):
+ pass
+
+
+class ZteZxrosTelnet(ZteZxrosBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ ZTE need manually reply DO ECHO to enable echo command.
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Height:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+
+
+
+
+
+
+
+
+class ZteZxrosBase
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZteZxrosBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+Ancestors
+
+Subclasses
+
+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: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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='write', confirm=False, confirm_response='')
+
+-
+
Saves Config Using Copy Run Start
+
+Source code
+def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+) -> str:
+ """Saves Config Using Copy Run Start"""
+ 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) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+
+
+Inherited members
+
+
+
+class ZteZxrosSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZteZxrosSSH(ZteZxrosBase):
+ pass
+
+Ancestors
+
+Inherited members
+
+
+
+class ZteZxrosTelnet
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
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.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZteZxrosTelnet(ZteZxrosBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ ZTE need manually reply DO ECHO to enable echo command.
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Height:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
+
+Ancestors
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/zyxel/index.html b/docs/netmiko/zyxel/index.html
new file mode 100644
index 000000000..771c1a05e
--- /dev/null
+++ b/docs/netmiko/zyxel/index.html
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+netmiko.zyxel API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Source code
+from netmiko.zyxel.zyxel_ssh import ZyxelSSH
+
+
+__all__ = ["ZyxelSSH"]
+
+
+
+
+
+
+
+
+
+class ZyxelSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZyxelSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+ def session_preparation(self) -> None:
+ super().session_preparation()
+ # Zyxel switches output ansi codes
+ self.ansi_escape_codes = True
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=False, enter_config_mode=False, **kwargs)
+
+-
+
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/netmiko/zyxel/zyxel_ssh.html b/docs/netmiko/zyxel/zyxel_ssh.html
new file mode 100644
index 000000000..6dd88ccac
--- /dev/null
+++ b/docs/netmiko/zyxel/zyxel_ssh.html
@@ -0,0 +1,336 @@
+
+
+
+
+
+
+netmiko.zyxel.zyxel_ssh API documentation
+
+
+
+
+
+
+
+
+
+
+
+
+Module netmiko.zyxel.zyxel_ssh
+
+
+
+Source code
+from typing import Any, Sequence, TextIO, Union
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+
+
+class ZyxelSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+ def session_preparation(self) -> None:
+ super().session_preparation()
+ # Zyxel switches output ansi codes
+ self.ansi_escape_codes = True
+
+
+
+
+
+
+
+
+
+class ZyxelSSH
+(ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1.0, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, disabled_algorithms=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=10, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, read_timeout_override=None, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=True, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True, delay_factor_compat=False)
+
+-
+
Class for platforms that have no enable mode.
+Netmiko translates the meaning of "enable" mode to be a proxy for "can
+go into config mode". In other words, that you ultimately have privileges
+to execute configuration changes.
+The expectation on platforms that have no method for elevating privileges
+is that the standard default privileges allow configuration changes.
+Consequently check_enable_mode returns True by default for platforms that
+don't explicitly support enable mode.
+ Initialize attributes for establishing connection to target device.
+
+ :param ip: IP address of target device. Not required if `host` is
+ provided.
+
+ :param host: Hostname of target device. Not required if `ip` is
+ provided.
+
+ :param username: Username to authenticate against target device if
+ required.
+
+ :param password: Password to authenticate against target device if
+ required.
+
+ :param secret: The enable password if target device requires one.
+
+ :param port: The destination port used to connect to the target
+ device.
+
+ :param device_type: Class selection based on device type.
+
+ :param verbose: Enable additional messages to standard output.
+
+ :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+
+ :param use_keys: Connect to target device using SSH keys.
+
+ :param key_file: Filename path of the SSH key file to use.
+
+ :param pkey: SSH key object to use.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
+
+ :param allow_agent: Enable use of SSH key-agent.
+
+ :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+ means unknown SSH host keys will be accepted).
+
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
+ :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+ alt_key_file.
+
+ :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+
+ :param ssh_config_file: File name of OpenSSH configuration file.
+
+ :param timeout: Connection timeout.
+
+ :param session_timeout: Set a timeout for parallel requests.
+
+ :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+
+ :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).
+
+ :param default_enter: Character(s) to send to correspond to enter key (default:
+
+).
+ :param response_return: Character(s) to use in normalized return data to represent
+ enter key (default:
+
+)
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
+
+
+Source code
+class ZyxelSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+ def session_preparation(self) -> None:
+ super().session_preparation()
+ # Zyxel switches output ansi codes
+ self.ansi_escape_codes = True
+
+Ancestors
+
+Methods
+
+
+def disable_paging(self, *args, **kwargs)
+
+-
+
+
+Source code
+def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+
+
+def send_config_set(self, config_commands=None, exit_config_mode=False, enter_config_mode=False, **kwargs)
+
+-
+
+
+Source code
+def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+
+
+Inherited members
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/source/classes.rst b/docs/source/classes.rst
deleted file mode 100644
index b486a9c3b..000000000
--- a/docs/source/classes.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Netmiko Classes
-===============
-
-.. toctree ::
- :maxdepth: 2
-
- classes/base_connection
diff --git a/docs/source/classes/base_connection.rst b/docs/source/classes/base_connection.rst
deleted file mode 100644
index 512f1981a..000000000
--- a/docs/source/classes/base_connection.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-BaseConnection
-==============
-
-.. autoclass:: netmiko.base_connection.BaseConnection
- :members:
- :special-members:
diff --git a/docs/source/conf.py b/docs/source/conf.py
deleted file mode 100644
index e483c4bc5..000000000
--- a/docs/source/conf.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Netmiko documentation build configuration file, created by
-# sphinx-quickstart on Tue Oct 11 21:21:53 2016.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-import os
-import sys
-sys.path.insert(0, os.path.abspath('../..'))
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#
-# needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
- 'sphinx.ext.autodoc',
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix(es) of source filenames.
-# You can specify multiple suffix as a list of string:
-#
-# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
-
-# The encoding of source files.
-#
-# source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Netmiko'
-copyright = u'2016, Kirk Byers'
-author = u'Kirk Byers'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = u'1.0'
-# The full version, including alpha/beta/rc tags.
-release = u'1.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#
-# This is also used if you do content translation via gettext catalogs.
-# Usually you set "language" from the command line for these cases.
-language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#
-# today = ''
-#
-# Else, today_fmt is used as the format for a strftime call.
-#
-# today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = []
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#
-# default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#
-# add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#
-# add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#
-# show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-# modindex_common_prefix = []
-
-# If true, keep warnings as "system message" paragraphs in the built documents.
-# keep_warnings = False
-
-# If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = False
-
-
-# -- Options for HTML output ----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = 'sphinx_rtd_theme'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-# html_theme_path = []
-
-# The name for this set of Sphinx documents.
-# " v documentation" by default.
-#
-# html_title = u'Netmiko v1.0'
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#
-# html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#
-# html_logo = None
-
-# The name of an image file (relative to this directory) to use as a favicon of
-# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#
-# html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# Add any extra paths that contain custom files (such as robots.txt or
-# .htaccess) here, relative to this directory. These files are copied
-# directly to the root of the documentation.
-#
-# html_extra_path = []
-
-# If not None, a 'Last updated on:' timestamp is inserted at every page
-# bottom, using the given strftime format.
-# The empty string is equivalent to '%b %d, %Y'.
-#
-# html_last_updated_fmt = None
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#
-# html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#
-# html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#
-# html_additional_pages = {}
-
-# If false, no module index is generated.
-#
-# html_domain_indices = True
-
-# If false, no index is generated.
-#
-# html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#
-# html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#
-# html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#
-# html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#
-# html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#
-# html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = None
-
-# Language to be used for generating the HTML full-text search index.
-# Sphinx supports the following languages:
-# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
-# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
-#
-# html_search_language = 'en'
-
-# A dictionary with options for the search language support, empty by default.
-# 'ja' uses this config value.
-# 'zh' user can custom change `jieba` dictionary path.
-#
-# html_search_options = {'type': 'default'}
-
-# The name of a javascript file (relative to the configuration directory) that
-# implements a search results scorer. If empty, the default will be used.
-#
-# html_search_scorer = 'scorer.js'
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Netmikodoc'
-
-# -- Options for LaTeX output ---------------------------------------------
-
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- #
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- #
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- #
- # 'preamble': '',
-
- # Latex figure (float) alignment
- #
- # 'figure_align': 'htbp',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto, manual, or own class]).
-latex_documents = [
- (master_doc, 'Netmiko.tex', u'Netmiko Documentation',
- u'Kirk Byers', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#
-# latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#
-# latex_use_parts = False
-
-# If true, show page references after internal links.
-#
-# latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#
-# latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#
-# latex_appendices = []
-
-# It false, will not define \strong, \code, itleref, \crossref ... but only
-# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
-# packages.
-#
-# latex_keep_old_macro_names = True
-
-# If false, no module index is generated.
-#
-# latex_domain_indices = True
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'netmiko', u'Netmiko Documentation',
- [author], 1)
-]
-
-# If true, show URL addresses after external links.
-#
-# man_show_urls = False
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (master_doc, 'Netmiko', u'Netmiko Documentation',
- author, 'Netmiko', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#
-# texinfo_appendices = []
-
-# If false, no module index is generated.
-#
-# texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#
-# texinfo_show_urls = 'footnote'
-
-# If true, do not generate a @detailmenu in the "Top" node's menu.
-#
-# texinfo_no_detailmenu = False
diff --git a/docs/source/index.rst b/docs/source/index.rst
deleted file mode 100644
index fef22d5e2..000000000
--- a/docs/source/index.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-.. Netmiko documentation master file, created by
- sphinx-quickstart on Tue Oct 11 21:21:53 2016.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to Netmiko's documentation!
-===================================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- classes
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/examples/adding_delay/add_delay.py b/examples/adding_delay/add_delay.py
deleted file mode 100755
index 75f6d275c..000000000
--- a/examples/adding_delay/add_delay.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': "host.domain.com",
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
- # Increase (essentially) all sleeps by a factor of 2
- 'global_delay_factor': 2,
-}
-
-net_connect = Netmiko(**my_device)
-# Increase the sleeps for just send_command by a factor of 2
-output = net_connect.send_command("show ip int brief", delay_factor=2)
-print(output)
-net_connect.disconnect()
diff --git a/examples/asa_upgrade.py b/examples/asa_upgrade.py
deleted file mode 100755
index 62c48853d..000000000
--- a/examples/asa_upgrade.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env python
-"""Script to upgrade a Cisco ASA."""
-from __future__ import print_function
-from datetime import datetime
-from getpass import getpass
-from netmiko import ConnectHandler, FileTransfer
-
-
-def asa_scp_handler(ssh_conn, cmd='ssh scopy enable', mode='enable'):
- """Enable/disable SCP on Cisco ASA."""
- if mode == 'disable':
- cmd = 'no ' + cmd
- return ssh_conn.send_config_set([cmd])
-
-
-def main():
- """Script to upgrade a Cisco ASA."""
- try:
- ip_addr = raw_input("Enter ASA IP address: ")
- except NameError:
- ip_addr = input("Enter ASA IP address: ")
- my_pass = getpass()
- start_time = datetime.now()
- print(">>>> {}".format(start_time))
-
- net_device = {
- 'device_type': 'cisco_asa',
- 'ip': ip_addr,
- 'username': 'admin',
- 'password': my_pass,
- 'secret': my_pass,
- 'port': 22,
- }
-
- print("\nLogging in to ASA")
- ssh_conn = ConnectHandler(**net_device)
- print()
-
- # ADJUST TO TRANSFER IMAGE FILE
- dest_file_system = 'disk0:'
- source_file = 'test1.txt'
- dest_file = 'test1.txt'
- alt_dest_file = 'asa825-59-k8.bin'
-
- with FileTransfer(ssh_conn, source_file=source_file, dest_file=dest_file,
- file_system=dest_file_system) as scp_transfer:
-
- if not scp_transfer.check_file_exists():
- if not scp_transfer.verify_space_available():
- raise ValueError("Insufficient space available on remote device")
-
- print("Enabling SCP")
- output = asa_scp_handler(ssh_conn, mode='enable')
- print(output)
-
- print("\nTransferring file\n")
- scp_transfer.transfer_file()
-
- print("Disabling SCP")
- output = asa_scp_handler(ssh_conn, mode='disable')
- print(output)
-
- print("\nVerifying file")
- if scp_transfer.verify_file():
- print("Source and destination MD5 matches")
- else:
- raise ValueError("MD5 failure between source and destination files")
-
- print("\nSending boot commands")
- full_file_name = "{}/{}".format(dest_file_system, alt_dest_file)
- boot_cmd = 'boot system {}'.format(full_file_name)
- output = ssh_conn.send_config_set([boot_cmd])
- print(output)
-
- print("\nVerifying state")
- output = ssh_conn.send_command('show boot')
- print(output)
-
- # UNCOMMENT TO PERFORM WR MEM AND RELOAD
- # print("\nWrite mem and reload")
- # output = ssh_conn.send_command_expect('write mem')
- # output += ssh_conn.send_command('reload')
- # output += ssh_conn.send_command('y')
- # print(output)
-
- print("\n>>>> {}".format(datetime.now() - start_time))
- print()
-
-
-if __name__ == "__main__":
- main()
diff --git a/examples/autodetect_snmp.py b/examples/autodetect_snmp.py
new file mode 100644
index 000000000..f5263fe58
--- /dev/null
+++ b/examples/autodetect_snmp.py
@@ -0,0 +1,20 @@
+import sys
+from getpass import getpass
+from netmiko.snmp_autodetect import SNMPDetect
+from netmiko import ConnectHandler
+
+host = "cisco1.lasthop.io"
+device = {"host": host, "username": "pyclass", "password": getpass()}
+
+snmp_community = getpass("Enter SNMP community: ")
+my_snmp = SNMPDetect(host, snmp_version="v2c", community=snmp_community)
+device_type = my_snmp.autodetect()
+print(device_type)
+
+if device_type is None:
+ sys.exit("SNMP failed!")
+
+# Update the device dictionary with the device_type and connect
+device["device_type"] = device_type
+with ConnectHandler(**device) as net_connect:
+ print(net_connect.find_prompt())
diff --git a/examples/autodetect_snmp_v3.py b/examples/autodetect_snmp_v3.py
new file mode 100644
index 000000000..55dfa3524
--- /dev/null
+++ b/examples/autodetect_snmp_v3.py
@@ -0,0 +1,29 @@
+# SNMPv3
+import sys
+from getpass import getpass
+from netmiko.snmp_autodetect import SNMPDetect
+from netmiko import ConnectHandler
+
+device = {"host": "cisco1.lasthop.io", "username": "pyclass", "password": getpass()}
+
+snmp_key = getpass("Enter SNMP community: ")
+my_snmp = SNMPDetect(
+ "cisco1.lasthop.io",
+ snmp_version="v3",
+ user="pysnmp",
+ auth_key=snmp_key,
+ encrypt_key=snmp_key,
+ auth_proto="sha",
+ encrypt_proto="aes128",
+)
+device_type = my_snmp.autodetect()
+print(device_type)
+
+if device_type is None:
+ sys.exit("SNMP failed!")
+
+# Update the device_type with information discovered using SNMP
+device["device_type"] = device_type
+net_connect = ConnectHandler(**device)
+print(net_connect.find_prompt())
+net_connect.disconnect()
diff --git a/examples/autodetect_ssh.py b/examples/autodetect_ssh.py
new file mode 100644
index 000000000..cd60658b8
--- /dev/null
+++ b/examples/autodetect_ssh.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+from netmiko import SSHDetect, ConnectHandler
+from getpass import getpass
+
+device = {
+ "device_type": "autodetect",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+guesser = SSHDetect(**device)
+best_match = guesser.autodetect()
+print(best_match) # Name of the best device_type to use further
+print(guesser.potential_matches) # Dictionary of the whole matching result
+# Update the 'device' dictionary with the device_type
+device["device_type"] = best_match
+
+with ConnectHandler(**device) as connection:
+ print(connection.find_prompt())
diff --git a/examples/config_change.py b/examples/config_change.py
new file mode 100644
index 000000000..c614a0bac
--- /dev/null
+++ b/examples/config_change.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+device = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+commands = ["logging buffered 100000"]
+with ConnectHandler(**device) as net_connect:
+ output = net_connect.send_config_set(commands)
+ output += net_connect.save_config()
+
+print()
+print(output)
+print()
diff --git a/examples/config_change_file.py b/examples/config_change_file.py
new file mode 100644
index 000000000..38d0010cf
--- /dev/null
+++ b/examples/config_change_file.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+device1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+# File in same directory as script that contains
+#
+# $ cat config_changes.txt
+# --------------
+# logging buffered 100000
+# no logging console
+
+cfg_file = "config_changes.txt"
+with ConnectHandler(**device1) as net_connect:
+ output = net_connect.send_config_from_file(cfg_file)
+ output += net_connect.save_config()
+
+print()
+print(output)
+print()
diff --git a/examples/config_changes.txt b/examples/config_changes.txt
new file mode 100644
index 000000000..8bbe9ba01
--- /dev/null
+++ b/examples/config_changes.txt
@@ -0,0 +1,2 @@
+logging buffered 100000
+no logging console
diff --git a/examples/configuration_changes/change_file.txt b/examples/configuration_changes/change_file.txt
deleted file mode 100644
index b331444e6..000000000
--- a/examples/configuration_changes/change_file.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-logging buffered 8000
-logging console
diff --git a/examples/configuration_changes/config_changes.py b/examples/configuration_changes/config_changes.py
deleted file mode 100755
index fbe18f52a..000000000
--- a/examples/configuration_changes/config_changes.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': "host.domain.com",
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-cfg_commands = ['logging buffered 10000', 'no logging console']
-
-# send_config_set() will automatically enter/exit config mode
-output = net_connect.send_config_set(cfg_commands)
-print(output)
-
-net_connect.disconnect()
diff --git a/examples/configuration_changes/config_changes_from_file.py b/examples/configuration_changes/config_changes_from_file.py
deleted file mode 100755
index c5b0eaa88..000000000
--- a/examples/configuration_changes/config_changes_from_file.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': "host.domain.com",
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-
-# Make configuration changes using an external file
-output = net_connect.send_config_from_file("change_file.txt")
-print(output)
-
-net_connect.disconnect()
diff --git a/examples/conn_multiple_dev.py b/examples/conn_multiple_dev.py
new file mode 100644
index 000000000..926b3c9d3
--- /dev/null
+++ b/examples/conn_multiple_dev.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+password = getpass()
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": password,
+}
+
+cisco2 = {
+ "device_type": "cisco_ios",
+ "host": "cisco2.lasthop.io",
+ "username": "pyclass",
+ "password": password,
+}
+
+nxos1 = {
+ "device_type": "cisco_nxos",
+ "host": "nxos1.lasthop.io",
+ "username": "pyclass",
+ "password": password,
+}
+
+srx1 = {
+ "device_type": "juniper_junos",
+ "host": "srx1.lasthop.io",
+ "username": "pyclass",
+ "password": password,
+}
+
+for device in (cisco1, cisco2, nxos1, srx1):
+ net_connect = ConnectHandler(**device)
+ print(net_connect.find_prompt())
+ net_connect.disconnect()
diff --git a/examples/conn_ssh_keys.py b/examples/conn_ssh_keys.py
new file mode 100644
index 000000000..42e1d0816
--- /dev/null
+++ b/examples/conn_ssh_keys.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+
+key_file = "~/.ssh/test_rsa"
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "testuser",
+ "use_keys": True,
+ "key_file": key_file,
+}
+
+with ConnectHandler(**cisco1) as net_connect:
+ output = net_connect.send_command("show ip arp")
+
+print(f"\n{output}\n")
diff --git a/examples/conn_ssh_proxy.py b/examples/conn_ssh_proxy.py
new file mode 100644
index 000000000..309334354
--- /dev/null
+++ b/examples/conn_ssh_proxy.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+ "ssh_config_file": "~/.ssh/ssh_config",
+}
+
+with ConnectHandler(**cisco1) as net_connect:
+ output = net_connect.send_command("show users")
+
+print(f"\n{output}\n")
diff --git a/examples/conn_with_dict.py b/examples/conn_with_dict.py
new file mode 100644
index 000000000..d778c6060
--- /dev/null
+++ b/examples/conn_with_dict.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+ "device_type": "cisco_ios",
+}
+
+net_connect = ConnectHandler(**cisco1)
+print(net_connect.find_prompt())
+net_connect.disconnect()
diff --git a/examples/conn_with_dict_cm.py b/examples/conn_with_dict_cm.py
new file mode 100644
index 000000000..dcc9da0f1
--- /dev/null
+++ b/examples/conn_with_dict_cm.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+# Will automatically 'disconnect()'
+with ConnectHandler(**cisco1) as net_connect:
+ print(net_connect.find_prompt())
diff --git a/examples/connect_multiple_devices/connect_multiple.py b/examples/connect_multiple_devices/connect_multiple.py
deleted file mode 100755
index ba67218a7..000000000
--- a/examples/connect_multiple_devices/connect_multiple.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-"""
-This example is serial (i.e. no concurrency). Connect to one device, after the other,
-after the other.
-"""
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-password = getpass()
-
-cisco1 = {
- 'host': "host1.domain.com",
- 'username': 'pyclass',
- 'password': password,
- 'device_type': 'cisco_ios',
-}
-
-arista1 = {
- 'host': "host2.domain.com",
- 'username': 'pyclass',
- 'password': password,
- 'device_type': 'arista_eos',
-}
-
-srx1 = {
- 'host': "host3.domain.com",
- 'username': 'pyclass',
- 'password': password,
- 'device_type': 'juniper_junos',
-}
-
-for device in (cisco1, arista1, srx1):
- net_connect = Netmiko(**device)
- print(net_connect.find_prompt())
diff --git a/examples/delay_factor.py b/examples/delay_factor.py
new file mode 100644
index 000000000..570518363
--- /dev/null
+++ b/examples/delay_factor.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+from datetime import datetime
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+command = "copy flash:c880data-universalk9-mz.155-3.M8.bin flash:test1.bin"
+
+# Start clock
+start_time = datetime.now()
+
+net_connect = ConnectHandler(**cisco1)
+
+# Netmiko normally allows 100 seconds for send_command to complete
+# delay_factor=4 would allow 400 seconds.
+output = net_connect.send_command_timing(
+ command, strip_prompt=False, strip_command=False, delay_factor=4
+)
+if "Destination filename" in output:
+ print("Starting copy...")
+ output += net_connect.send_command("\n", delay_factor=4, expect_string=r"#")
+net_connect.disconnect()
+
+end_time = datetime.now()
+print(f"\n{output}\n")
+print("done")
+print(f"Execution time: {start_time - end_time}")
diff --git a/examples/enable.py b/examples/enable.py
new file mode 100644
index 000000000..a8ec0c09e
--- /dev/null
+++ b/examples/enable.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+password = getpass()
+secret = getpass("Enter secret: ")
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": password,
+ "secret": secret,
+}
+
+net_connect = ConnectHandler(**cisco1)
+# Call 'enable()' method to elevate privileges
+net_connect.enable()
+print(net_connect.find_prompt())
diff --git a/examples/enable/enable.py b/examples/enable/enable.py
deleted file mode 100755
index 8c14df8b6..000000000
--- a/examples/enable/enable.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': "host.domain.com",
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-# Ensure in enable mode
-net_connect.enable()
-print(net_connect.find_prompt())
-
-net_connect.disconnect()
diff --git a/examples/global_delay_factor.py b/examples/global_delay_factor.py
new file mode 100644
index 000000000..a06c2fca4
--- /dev/null
+++ b/examples/global_delay_factor.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+ # Multiple all of the delays by a factor of two
+ "global_delay_factor": 2,
+}
+
+command = "show ip arp"
+net_connect = ConnectHandler(**cisco1)
+output = net_connect.send_command(command)
+net_connect.disconnect()
+
+print(f"\n{output}\n")
diff --git a/examples/handle_prompts/handle_prompts.py b/examples/handle_prompts/handle_prompts.py
deleted file mode 100755
index 409c95d04..000000000
--- a/examples/handle_prompts/handle_prompts.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-"""Handling commands that prompt for additional information."""
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': "host.domain.com",
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-"""
-Cisco IOS behavior on file delete:
-
-pynet-rtr1# delete flash:/small_file_bim.txt
-Delete flash:/test1.txt? [confirm]y
-pynet-rtr1
-"""
-
-net_connect = Netmiko(**my_device)
-filename = "text1234.txt"
-cmd = "delete flash:{}".format(filename)
-
-# send_command_timing as the router prompt is not returned
-output = net_connect.send_command_timing(cmd, strip_command=False, strip_prompt=False)
-if 'confirm' in output:
- output += net_connect.send_command_timing("\n", strip_command=False, strip_prompt=False)
-
-net_connect.disconnect()
-print(output)
diff --git a/examples/invalid_device_type.py b/examples/invalid_device_type.py
new file mode 100644
index 000000000..7a2d05478
--- /dev/null
+++ b/examples/invalid_device_type.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+
+cisco1 = {
+ # Just pick an 'invalid' device_type
+ "device_type": "invalid",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": "invalid",
+}
+
+net_connect = ConnectHandler(**cisco1)
+net_connect.disconnect()
diff --git a/examples/netmiko_logging.py b/examples/netmiko_logging.py
new file mode 100644
index 000000000..1e80efbd8
--- /dev/null
+++ b/examples/netmiko_logging.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+# Logging section ##############
+import logging
+
+logging.basicConfig(filename="test.log", level=logging.DEBUG)
+logger = logging.getLogger("netmiko")
+# Logging section ##############
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+net_connect = ConnectHandler(**cisco1)
+print(net_connect.find_prompt())
+net_connect.disconnect()
diff --git a/examples/secure_copy.py b/examples/secure_copy.py
new file mode 100644
index 000000000..181c2cb7c
--- /dev/null
+++ b/examples/secure_copy.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+from getpass import getpass
+from netmiko import ConnectHandler, file_transfer
+
+cisco = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+source_file = "test1.txt"
+dest_file = "test1.txt"
+direction = "put"
+file_system = "flash:"
+
+ssh_conn = ConnectHandler(**cisco)
+transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ # Force an overwrite of the file if it already exists
+ overwrite_file=True,
+)
+
+print(transfer_dict)
diff --git a/examples/send_command.py b/examples/send_command.py
new file mode 100644
index 000000000..03a2c8a47
--- /dev/null
+++ b/examples/send_command.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+# Show command that we execute
+command = "show ip int brief"
+with ConnectHandler(**cisco1) as net_connect:
+ output = net_connect.send_command(command)
+
+# Automatically cleans-up the output so that only the show output is returned
+print()
+print(output)
+print()
diff --git a/examples/send_command_genie.py b/examples/send_command_genie.py
new file mode 100644
index 000000000..3e5e89115
--- /dev/null
+++ b/examples/send_command_genie.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+from getpass import getpass
+from pprint import pprint
+from netmiko import ConnectHandler
+
+device = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+with ConnectHandler(**device) as net_connect:
+ output = net_connect.send_command("show ip interface brief", use_genie=True)
+
+print()
+pprint(output)
+print()
diff --git a/examples/send_command_prompting.py b/examples/send_command_prompting.py
new file mode 100644
index 000000000..9d98742b3
--- /dev/null
+++ b/examples/send_command_prompting.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+command = "del flash:/test3.txt"
+net_connect = ConnectHandler(**cisco1)
+
+# CLI Interaction is as follows:
+# cisco1#delete flash:/testb.txt
+# Delete filename [testb.txt]?
+# Delete flash:/testb.txt? [confirm]y
+
+# Use 'send_command_timing' which is entirely delay based.
+# strip_prompt=False and strip_command=False make the output
+# easier to read in this context.
+output = net_connect.send_command_timing(
+ command_string=command, strip_prompt=False, strip_command=False
+)
+if "Delete filename" in output:
+ output += net_connect.send_command_timing(
+ command_string="\n", strip_prompt=False, strip_command=False
+ )
+if "confirm" in output:
+ output += net_connect.send_command_timing(
+ command_string="y", strip_prompt=False, strip_command=False
+ )
+net_connect.disconnect()
+
+print()
+print(output)
+print()
diff --git a/examples/send_command_prompting_expect.py b/examples/send_command_prompting_expect.py
new file mode 100644
index 000000000..f189621b2
--- /dev/null
+++ b/examples/send_command_prompting_expect.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+command = "del flash:/test4.txt"
+net_connect = ConnectHandler(**cisco1)
+
+# CLI Interaction is as follows:
+# cisco1#delete flash:/testb.txt
+# Delete filename [testb.txt]?
+# Delete flash:/testb.txt? [confirm]y
+
+# Use 'send_command' and the 'expect_string' argument (note, expect_string uses
+# RegEx patterns). Netmiko will move-on to the next command when the
+# 'expect_string' is detected.
+
+# strip_prompt=False and strip_command=False make the output
+# easier to read in this context.
+output = net_connect.send_command(
+ command_string=command,
+ expect_string=r"Delete filename",
+ strip_prompt=False,
+ strip_command=False,
+)
+output += net_connect.send_command(
+ command_string="\n",
+ expect_string=r"confirm",
+ strip_prompt=False,
+ strip_command=False,
+)
+output += net_connect.send_command(
+ command_string="y", expect_string=r"#", strip_prompt=False, strip_command=False
+)
+net_connect.disconnect()
+
+print()
+print(output)
+print()
diff --git a/examples/send_command_textfsm.py b/examples/send_command_textfsm.py
new file mode 100644
index 000000000..da2bcaa2d
--- /dev/null
+++ b/examples/send_command_textfsm.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+from pprint import pprint
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+command = "show ip int brief"
+with ConnectHandler(**cisco1) as net_connect:
+ # Use TextFSM to retrieve structured data
+ output = net_connect.send_command(command, use_textfsm=True)
+
+print()
+pprint(output)
+print()
diff --git a/examples/send_command_ttp.py b/examples/send_command_ttp.py
new file mode 100644
index 000000000..249f6b55c
--- /dev/null
+++ b/examples/send_command_ttp.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+from pprint import pprint
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+}
+
+# write template to file
+ttp_raw_template = """
+interface {{ interface }}
+ description {{ description }}
+"""
+
+with open("show_run_interfaces.ttp", "w") as writer:
+ writer.write(ttp_raw_template)
+
+command = "show run"
+with ConnectHandler(**cisco1) as net_connect:
+ # Use TTP to retrieve structured data
+ output = net_connect.send_command(
+ command, use_ttp=True, ttp_template="show_run_interfaces.ttp"
+ )
+
+print()
+pprint(output)
+print()
diff --git a/examples/session_log.py b/examples/session_log.py
new file mode 100644
index 000000000..39df5786c
--- /dev/null
+++ b/examples/session_log.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+from netmiko import ConnectHandler
+from getpass import getpass
+
+cisco1 = {
+ "device_type": "cisco_ios",
+ "host": "cisco1.lasthop.io",
+ "username": "pyclass",
+ "password": getpass(),
+ "session_log": "output.txt",
+}
+
+# Show command that we execute
+command = "show ip int brief"
+with ConnectHandler(**cisco1) as net_connect:
+ output = net_connect.send_command(command)
diff --git a/examples/show_command/show_command.py b/examples/show_command/show_command.py
deleted file mode 100755
index 51fc25d4e..000000000
--- a/examples/show_command/show_command.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': 'host.domain.com',
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-
-output = net_connect.send_command("show ip int brief")
-print(output)
-
-net_connect.disconnect()
diff --git a/examples/show_command/show_command_textfsm.py b/examples/show_command/show_command_textfsm.py
deleted file mode 100755
index 6a3e9c783..000000000
--- a/examples/show_command/show_command_textfsm.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': 'host.domain.com',
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-# Requires ntc-templates to be installed in ~/ntc-templates/templates
-output = net_connect.send_command("show ip int brief", use_textfsm=True)
-print(output)
diff --git a/examples/simple_conn.py b/examples/simple_conn.py
new file mode 100644
index 000000000..3f2c67cd5
--- /dev/null
+++ b/examples/simple_conn.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+from netmiko import Netmiko
+from getpass import getpass
+
+net_connect = Netmiko(
+ "cisco1.twb-tech.com",
+ username="pyclass",
+ password=getpass(),
+ device_type="cisco_ios",
+)
+
+print(net_connect.find_prompt())
+net_connect.disconnect()
diff --git a/examples/simple_connection/simple_conn.py b/examples/simple_connection/simple_conn.py
deleted file mode 100755
index 535a73095..000000000
--- a/examples/simple_connection/simple_conn.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-net_connect = Netmiko(host='host.domain.com', username='pyclass',
- password=getpass(), device_type='cisco_ios')
-
-print(net_connect.find_prompt())
-net_connect.disconnect()
diff --git a/examples/simple_connection/simple_conn_dict.py b/examples/simple_connection/simple_conn_dict.py
deleted file mode 100755
index 5ece4dd95..000000000
--- a/examples/simple_connection/simple_conn_dict.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-# Netmiko is the same as ConnectHandler
-from netmiko import Netmiko
-from getpass import getpass
-
-my_device = {
- 'host': 'host.domain.com',
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-print(net_connect.find_prompt())
-net_connect.disconnect()
diff --git a/examples/ssh_config b/examples/ssh_config
new file mode 100644
index 000000000..deb818fd3
--- /dev/null
+++ b/examples/ssh_config
@@ -0,0 +1,12 @@
+host jumphost
+ IdentitiesOnly yes
+ IdentityFile ~/.ssh/test_rsa
+ User gituser
+ HostName pynetqa.lasthop.io
+
+host * !jumphost
+ User pyclass
+ # Force usage of this SSH config file
+ ProxyCommand ssh -F ~/.ssh/ssh_config -W %h:%p jumphost
+ # Alternate solution using netcat
+ #ProxyCommand ssh -F ./ssh_config jumphost nc %h %p
diff --git a/examples/term_server.py b/examples/term_server.py
new file mode 100644
index 000000000..c825104bb
--- /dev/null
+++ b/examples/term_server.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+"""
+This is a complicated example, but it illustrates both using a terminal server
+and bouncing through multiple devices.
+
+It also illustrates using 'redispatch()' to dynamically switch the Netmiko class
+
+The setup here is:
+
+Linux Server --(ssh)--> Small Switch --(telnet)--> Terminal Server --(serial)--> Juniper SRX
+"""
+import os
+from getpass import getpass
+from netmiko import ConnectHandler, redispatch
+
+# Hiding these IP addresses
+terminal_server_ip = os.environ["TERMINAL_SERVER_IP"]
+public_ip = os.environ["PUBLIC_IP"]
+
+s300_pass = getpass("Enter password of s300: ")
+term_serv_pass = getpass("Enter the terminal server password: ")
+srx2_pass = getpass("Enter SRX2 password: ")
+
+# For internal reasons I have to bounce through this small switch to access
+# my terminal server.
+device = {
+ "device_type": "cisco_s300",
+ "host": public_ip,
+ "username": "admin",
+ "password": s300_pass,
+ "session_log": "output.txt",
+}
+
+# Initial connection to the S300 switch
+net_connect = ConnectHandler(**device)
+print(net_connect.find_prompt())
+
+# Update the password as the terminal server uses different credentials
+net_connect.password = term_serv_pass
+net_connect.secret = term_serv_pass
+# Telnet to the terminal server
+command = f"telnet {terminal_server_ip}\n"
+net_connect.write_channel(command)
+# Use the telnet_login() method to handle the login process
+net_connect.telnet_login()
+print(net_connect.find_prompt())
+
+# Made it to the terminal server (this terminal server is "cisco_ios")
+# Use redispatch to re-initialize the right class.
+redispatch(net_connect, device_type="cisco_ios")
+net_connect.enable()
+print(net_connect.find_prompt())
+
+# Now connect to the end-device via the terminal server (Juniper SRX2)
+net_connect.write_channel("srx2\n")
+# Update the credentials for SRX2 as these are different.
+net_connect.username = "pyclass"
+net_connect.password = srx2_pass
+# Use the telnet_login() method to connect to the SRX
+net_connect.telnet_login()
+redispatch(net_connect, device_type="juniper_junos")
+print(net_connect.find_prompt())
+
+# Now we could do something on the SRX
+output = net_connect.send_command("show version")
+print(output)
+
+net_connect.disconnect()
diff --git a/examples/test.log b/examples/test.log
new file mode 100644
index 000000000..68843deb7
--- /dev/null
+++ b/examples/test.log
@@ -0,0 +1,65 @@
+DEBUG:paramiko.transport:starting thread (client mode): 0x14f3a470
+DEBUG:paramiko.transport:Local version/idstring: SSH-2.0-paramiko_2.7.1
+DEBUG:paramiko.transport:Remote version/idstring: SSH-2.0-Cisco-1.25
+INFO:paramiko.transport:Connected (version 2.0, client Cisco-1.25)
+DEBUG:paramiko.transport:kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-sha1', 'hmac-sha1-96'] server mac:['hmac-sha1', 'hmac-sha1-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
+DEBUG:paramiko.transport:Kex agreed: diffie-hellman-group-exchange-sha1
+DEBUG:paramiko.transport:HostKey agreed: ssh-rsa
+DEBUG:paramiko.transport:Cipher agreed: aes128-ctr
+DEBUG:paramiko.transport:MAC agreed: hmac-sha1
+DEBUG:paramiko.transport:Compression agreed: none
+DEBUG:paramiko.transport:Got server p (2048 bits)
+DEBUG:paramiko.transport:kex engine KexGex specified hash_algo
+DEBUG:paramiko.transport:Switch to new keys ...
+DEBUG:paramiko.transport:Adding ssh-rsa host key for cisco1.lasthop.io: b'539a8d09e0dab9e8f7ef2b61ba1d5805'
+DEBUG:paramiko.transport:userauth is OK
+INFO:paramiko.transport:Authentication (password) successful!
+DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
+DEBUG:paramiko.transport:[chan 0] Max packet out: 4096 bytes
+DEBUG:paramiko.transport:Secsh channel 0 opened.
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:[find_prompt()]: prompt is cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:In disable_paging
+DEBUG:netmiko:Command: terminal length 0
+
+DEBUG:netmiko:write_channel: b'terminal length 0\n'
+DEBUG:netmiko:Pattern is: terminal\ length\ 0
+DEBUG:netmiko:_read_channel_expect read_data: t
+DEBUG:netmiko:_read_channel_expect read_data: erminal length 0
+cisco1#
+DEBUG:netmiko:Pattern found: terminal\ length\ 0 terminal length 0
+cisco1#
+DEBUG:netmiko:terminal length 0
+cisco1#
+DEBUG:netmiko:Exiting disable_paging
+DEBUG:netmiko:write_channel: b'terminal width 511\n'
+DEBUG:netmiko:Pattern is: terminal\ width\ 511
+DEBUG:netmiko:_read_channel_expect read_data: t
+DEBUG:netmiko:_read_channel_expect read_data: erminal width 511
+cisco1#
+DEBUG:netmiko:Pattern found: terminal\ width\ 511 terminal width 511
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:[find_prompt()]: prompt is cisco1#
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'exit\n'
diff --git a/examples/test1.txt b/examples/test1.txt
new file mode 100644
index 000000000..982793c32
--- /dev/null
+++ b/examples/test1.txt
@@ -0,0 +1 @@
+whatever
diff --git a/examples/troubleshooting/enable_logging.py b/examples/troubleshooting/enable_logging.py
deleted file mode 100755
index ca695f581..000000000
--- a/examples/troubleshooting/enable_logging.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-from __future__ import print_function, unicode_literals
-
-import logging
-from netmiko import Netmiko
-from getpass import getpass
-
-# This will create a file named 'test.log' in your current directory.
-# It will log all reads and writes on the SSH channel.
-logging.basicConfig(filename='test.log', level=logging.DEBUG)
-logger = logging.getLogger("netmiko")
-
-my_device = {
- 'host': 'host.domain.com',
- 'username': 'pyclass',
- 'password': getpass(),
- 'device_type': 'cisco_ios',
-}
-
-net_connect = Netmiko(**my_device)
-output = net_connect.send_command("show ip int brief")
-print(output)
-net_connect.disconnect()
diff --git a/examples_old/case12_telnet/conn_telnet.py b/examples_old/case12_telnet/conn_telnet.py
new file mode 100644
index 000000000..8f88c638c
--- /dev/null
+++ b/examples_old/case12_telnet/conn_telnet.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+from netmiko import Netmiko
+from getpass import getpass
+
+cisco1 = {
+ "host": "cisco1.twb-tech.com",
+ "username": "pyclass",
+ "password": getpass(),
+ "device_type": "cisco_ios_telnet",
+}
+
+net_connect = Netmiko(**cisco1)
+print(net_connect.send_command("show ip arp"))
+net_connect.disconnect()
diff --git a/examples_old/case15_netmiko_tools/.netmiko.yml_example b/examples_old/case15_netmiko_tools/.netmiko.yml_example
new file mode 100644
index 000000000..147fe98a9
--- /dev/null
+++ b/examples_old/case15_netmiko_tools/.netmiko.yml_example
@@ -0,0 +1,69 @@
+---
+
+# Dictionary is a device
+pynet_rtr1:
+ device_type: cisco_ios
+ host: cisco1.twb-tech.com
+ username: admin
+ password: cisco123
+ port: 22
+
+pynet_rtr2:
+ device_type: cisco_ios
+ ip: 10.10.10.71
+ username: admin
+ password: cisco123
+
+arista_sw1:
+ device_type: arista_eos
+ ip: 10.10.10.72
+ username: admin
+ password: cisco123
+
+arista_sw2:
+ device_type: arista_eos
+ ip: 10.10.10.73
+ username: admin
+ password: cisco123
+
+arista_sw3:
+ device_type: arista_eos
+ ip: 10.10.10.74
+ username: admin
+ password: cisco123
+
+arista_sw4:
+ device_type: arista_eos
+ ip: 10.10.10.75
+ username: admin
+ password: cisco123
+
+juniper_srx:
+ device_type: juniper
+ ip: 10.10.10.76
+ username: admin
+ password: cisco123
+
+cisco_asa:
+ device_type: cisco_asa
+ ip: 10.10.10.1
+ username: admin
+ password: cisco123
+ secret: secret
+
+# Any list is group of devices
+cisco:
+ - pynet_rtr1
+ - pynet_rtr2
+
+asa:
+ - cisco_asa
+
+arista:
+ - arista_sw1
+ - arista_sw2
+ - arista_sw3
+ - arista_sw4
+
+juniper:
+ - juniper_srx
diff --git a/examples_old/case15_netmiko_tools/vlans.txt b/examples_old/case15_netmiko_tools/vlans.txt
new file mode 100644
index 000000000..b60cdf4bd
--- /dev/null
+++ b/examples_old/case15_netmiko_tools/vlans.txt
@@ -0,0 +1,6 @@
+vlan 100
+ name red100
+vlan 101
+ name red101
+vlan 102
+ name red102
diff --git a/examples_old/case16_concurrency/my_devices.py b/examples_old/case16_concurrency/my_devices.py
new file mode 100644
index 000000000..539163f0e
--- /dev/null
+++ b/examples_old/case16_concurrency/my_devices.py
@@ -0,0 +1,62 @@
+from getpass import getpass
+
+std_pwd = getpass("Enter standard password: ")
+
+pynet_rtr1 = {
+ "device_type": "cisco_ios",
+ "ip": "10.10.247.70",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+pynet_rtr2 = {
+ "device_type": "cisco_ios",
+ "ip": "10.10.247.71",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+pynet_sw1 = {
+ "device_type": "arista_eos",
+ "ip": "10.10.247.72",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+pynet_sw2 = {
+ "device_type": "arista_eos",
+ "ip": "10.10.247.73",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+pynet_sw3 = {
+ "device_type": "arista_eos",
+ "ip": "10.10.247.74",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+pynet_sw4 = {
+ "device_type": "arista_eos",
+ "ip": "10.10.247.75",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+juniper_srx = {
+ "device_type": "juniper_junos",
+ "ip": "10.10.247.76",
+ "username": "pyclass",
+ "password": std_pwd,
+}
+
+device_list = [
+ pynet_rtr1,
+ pynet_rtr2,
+ pynet_sw1,
+ pynet_sw2,
+ pynet_sw3,
+ pynet_sw4,
+ juniper_srx,
+]
diff --git a/examples_old/case16_concurrency/processes_netmiko.py b/examples_old/case16_concurrency/processes_netmiko.py
new file mode 100644
index 000000000..321531107
--- /dev/null
+++ b/examples_old/case16_concurrency/processes_netmiko.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+"""
+Use processes and Netmiko to connect to each of the devices. Execute
+'show version' on each device. Record the amount of time required to do this.
+"""
+from __future__ import print_function, unicode_literals
+from multiprocessing import Process
+
+from datetime import datetime
+from netmiko import ConnectHandler
+from my_devices import device_list as devices
+
+
+def show_version(a_device):
+ """Execute show version command using Netmiko."""
+ remote_conn = ConnectHandler(**a_device)
+ print()
+ print("#" * 80)
+ print(remote_conn.send_command("show version"))
+ print("#" * 80)
+ print()
+
+
+def main():
+ """
+ Use processes and Netmiko to connect to each of the devices. Execute
+ 'show version' on each device. Record the amount of time required to do this.
+ """
+ start_time = datetime.now()
+
+ procs = []
+ for a_device in devices:
+ my_proc = Process(target=show_version, args=(a_device,))
+ my_proc.start()
+ procs.append(my_proc)
+
+ for a_proc in procs:
+ print(a_proc)
+ a_proc.join()
+
+ print("\nElapsed time: " + str(datetime.now() - start_time))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case16_concurrency/processes_netmiko_queue.py b/examples_old/case16_concurrency/processes_netmiko_queue.py
new file mode 100644
index 000000000..d4f865b07
--- /dev/null
+++ b/examples_old/case16_concurrency/processes_netmiko_queue.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+"""
+Use processes and Netmiko to connect to each of the devices. Execute
+'show version' on each device. Use a queue to pass the output back to the parent process.
+Record the amount of time required to do this.
+"""
+from __future__ import print_function, unicode_literals
+from multiprocessing import Process, Queue
+
+from datetime import datetime
+from netmiko import ConnectHandler
+from my_devices import device_list as devices
+
+
+def show_version_queue(a_device, output_q):
+ """
+ Use Netmiko to execute show version. Use a queue to pass the data back to
+ the main process.
+ """
+ output_dict = {}
+ remote_conn = ConnectHandler(**a_device)
+ hostname = remote_conn.base_prompt
+ output = ("#" * 80) + "\n"
+ output += remote_conn.send_command("show version") + "\n"
+ output += ("#" * 80) + "\n"
+ output_dict[hostname] = output
+ output_q.put(output_dict)
+
+
+def main():
+ """
+ Use processes and Netmiko to connect to each of the devices. Execute
+ 'show version' on each device. Use a queue to pass the output back to the parent process.
+ Record the amount of time required to do this.
+ """
+ start_time = datetime.now()
+ output_q = Queue(maxsize=20)
+
+ procs = []
+ for a_device in devices:
+ my_proc = Process(target=show_version_queue, args=(a_device, output_q))
+ my_proc.start()
+ procs.append(my_proc)
+
+ # Make sure all processes have finished
+ for a_proc in procs:
+ a_proc.join()
+
+ while not output_q.empty():
+ my_dict = output_q.get()
+ for k, val in my_dict.items():
+ print(k)
+ print(val)
+
+ print("\nElapsed time: " + str(datetime.now() - start_time))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case16_concurrency/threads_netmiko.py b/examples_old/case16_concurrency/threads_netmiko.py
new file mode 100644
index 000000000..35c649e3c
--- /dev/null
+++ b/examples_old/case16_concurrency/threads_netmiko.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+import threading
+from datetime import datetime
+from netmiko import ConnectHandler
+from my_devices import device_list as devices
+
+
+def show_version(a_device):
+ """Execute show version command using Netmiko."""
+ remote_conn = ConnectHandler(**a_device)
+ print()
+ print("#" * 80)
+ print(remote_conn.send_command_expect("show version"))
+ print("#" * 80)
+ print()
+
+
+def main():
+ """
+ Use threads and Netmiko to connect to each of the devices. Execute
+ 'show version' on each device. Record the amount of time required to do this.
+ """
+ start_time = datetime.now()
+
+ for a_device in devices:
+ my_thread = threading.Thread(target=show_version, args=(a_device,))
+ my_thread.start()
+
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ print(some_thread)
+ some_thread.join()
+
+ print("\nElapsed time: " + str(datetime.now() - start_time))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case17_jinja2/jinja2_crypto.py b/examples_old/case17_jinja2/jinja2_crypto.py
new file mode 100755
index 000000000..ae9b553e4
--- /dev/null
+++ b/examples_old/case17_jinja2/jinja2_crypto.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+import jinja2
+
+template_vars = {"isakmp_enable": True, "encryption": "aes", "dh_group": 5}
+
+cfg_template = """
+
+{%- if isakmp_enable %}
+crypto isakmp policy 10
+ encr {{ encryption }}
+ authentication pre-share
+ group {{ dh_group }}
+crypto isakmp key my_key address 1.1.1.1 no-xauth
+crypto isakmp keepalive 10 periodic
+{%- endif %}
+
+"""
+
+template = jinja2.Template(cfg_template)
+print(template.render(template_vars))
diff --git a/examples_old/case17_jinja2/jinja2_for_loop.py b/examples_old/case17_jinja2/jinja2_for_loop.py
new file mode 100755
index 000000000..4e1d8002d
--- /dev/null
+++ b/examples_old/case17_jinja2/jinja2_for_loop.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+import jinja2
+
+my_vlans = {
+ "501": "blue501",
+ "502": "blue502",
+ "503": "blue503",
+ "504": "blue504",
+ "505": "blue505",
+ "506": "blue506",
+ "507": "blue507",
+ "508": "blue508",
+}
+template_vars = {"vlans": my_vlans}
+
+vlan_template = """
+
+{%- for vlan_id, vlan_name in vlans.items() %}
+vlan {{ vlan_id }}
+ name {{ vlan_name }}
+{%- endfor %}
+
+"""
+
+template = jinja2.Template(vlan_template)
+print(template.render(template_vars))
diff --git a/examples_old/case17_jinja2/jinja2_ospf_file.py b/examples_old/case17_jinja2/jinja2_ospf_file.py
new file mode 100755
index 000000000..911864be5
--- /dev/null
+++ b/examples_old/case17_jinja2/jinja2_ospf_file.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+import jinja2
+
+template_file = "ospf_config.j2"
+with open(template_file) as f:
+ jinja_template = f.read()
+
+ospf_active_interfaces = ["Vlan1", "Vlan2"]
+area0_networks = ["10.10.10.0/24", "10.10.20.0/24", "10.10.30.0/24"]
+template_vars = {
+ "ospf_process_id": 10,
+ "ospf_priority": 100,
+ "ospf_active_interfaces": ospf_active_interfaces,
+ "ospf_area0_networks": area0_networks,
+}
+
+template = jinja2.Template(jinja_template)
+print(template.render(template_vars))
diff --git a/examples_old/case17_jinja2/jinja2_vlans.py b/examples_old/case17_jinja2/jinja2_vlans.py
new file mode 100755
index 000000000..f722d435b
--- /dev/null
+++ b/examples_old/case17_jinja2/jinja2_vlans.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+import jinja2
+
+template_vars = {"vlan_id": 400, "vlan_name": "red400"}
+
+vlan_template = """
+vlan {{ vlan_id }}
+ name {{ vlan_name }}
+
+"""
+
+template = jinja2.Template(vlan_template)
+print(template.render(template_vars))
diff --git a/examples_old/case17_jinja2/ospf_config.j2 b/examples_old/case17_jinja2/ospf_config.j2
new file mode 100644
index 000000000..10f4043a7
--- /dev/null
+++ b/examples_old/case17_jinja2/ospf_config.j2
@@ -0,0 +1,16 @@
+
+{%- if ospf_priority is defined %}
+interface Vlan1
+ ip ospf priority {{ ospf_priority }}
+{%- endif %}
+
+router ospf {{ ospf_process_id }}
+ passive-interface default
+ {%- for intf in ospf_active_interfaces %}
+ no passive-interface {{ intf }}
+ {%- endfor %}
+ {%- for network in ospf_area0_networks %}
+ network {{ network }} area 0.0.0.0
+ {%- endfor %}
+ max-lsa 12000
+
diff --git a/examples_old/case18_structured_data_genie/genie_show_mac_nxos.py b/examples_old/case18_structured_data_genie/genie_show_mac_nxos.py
new file mode 100644
index 000000000..1cabd45c0
--- /dev/null
+++ b/examples_old/case18_structured_data_genie/genie_show_mac_nxos.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from getpass import getpass
+from pprint import pprint
+from netmiko import ConnectHandler
+
+PASSWORD = getpass()
+
+
+def main():
+ conn = ConnectHandler(
+ host="nxos1.lasthop.io",
+ device_type="cisco_nxos",
+ username="username",
+ password=PASSWORD,
+ )
+ output = conn.send_command("show mac address-table", use_genie=True)
+ pprint(output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case18_structured_data_genie/genie_show_platform_iosxr.py b/examples_old/case18_structured_data_genie/genie_show_platform_iosxr.py
new file mode 100644
index 000000000..446a36ad9
--- /dev/null
+++ b/examples_old/case18_structured_data_genie/genie_show_platform_iosxr.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from getpass import getpass
+from pprint import pprint
+from netmiko import ConnectHandler
+
+PASSWORD = getpass()
+
+
+def main():
+ conn = ConnectHandler(
+ host="iosxr1.lasthop.io",
+ device_type="cisco_xr",
+ username="username",
+ password=PASSWORD,
+ )
+ output = conn.send_command("show platform", use_genie=True)
+ pprint(output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex1.py b/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex1.py
new file mode 100644
index 000000000..527ddd4d3
--- /dev/null
+++ b/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex1.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+from getpass import getpass
+from pprint import pprint
+from netmiko import ConnectHandler
+
+PASSWORD = getpass()
+
+
+def main():
+ conn = ConnectHandler(
+ host="cisco1.lasthop.io",
+ # "cisco_xe" device type will cause textfsm to not return structured data
+ device_type="cisco_xe",
+ username="username",
+ password=PASSWORD,
+ )
+ # Setting both `use_textfsm` and `use_genie` to True will try textfsm first
+ # if structured data is returned genie will be ignored. If textfsm does not
+ # return structured data netmiko will try to parse with genie
+ output = conn.send_command("show version", use_textfsm=True, use_genie=True)
+ # genie structured data returned
+ pprint(output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex2.py b/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex2.py
new file mode 100644
index 000000000..0135553fc
--- /dev/null
+++ b/examples_old/case18_structured_data_genie/genie_textfsm_combined_ex2.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+from getpass import getpass
+from pprint import pprint
+from netmiko import ConnectHandler
+
+PASSWORD = getpass()
+
+
+def main():
+ conn = ConnectHandler(
+ host="cisco1.lasthop.io",
+ device_type="cisco_ios",
+ username="username",
+ password=PASSWORD,
+ )
+ # Setting both `use_textfsm` and `use_genie` to True will try textfsm first
+ # if structured data is returned genie will be ignored. If textfsm does not
+ # return structured data netmiko will try to parse with genie
+ output = conn.send_command("show version", use_textfsm=True, use_genie=True)
+ # textfsm structured data returned
+ pprint(output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples_old/case7_commit/config_change_jnpr.py b/examples_old/case7_commit/config_change_jnpr.py
new file mode 100644
index 000000000..2a1bd938c
--- /dev/null
+++ b/examples_old/case7_commit/config_change_jnpr.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+from netmiko import Netmiko
+from getpass import getpass
+
+device = {
+ "host": "srx1.twb-tech.com",
+ "username": "pyclass",
+ "password": getpass(),
+ "device_type": "juniper_junos",
+}
+
+commands = ["set system syslog archive size 240k files 3 "]
+
+net_connect = Netmiko(**device)
+
+print()
+print(net_connect.find_prompt())
+output = net_connect.send_config_set(commands, exit_config_mode=False)
+output += net_connect.commit(and_quit=True)
+print(output)
+print()
+
+net_connect.disconnect()
diff --git a/examples_old/write_channel.py b/examples_old/write_channel.py
new file mode 100644
index 000000000..a7bfa38ae
--- /dev/null
+++ b/examples_old/write_channel.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from netmiko import Netmiko
+from getpass import getpass
+import time
+
+cisco1 = {
+ "host": "cisco1.twb-tech.com",
+ "username": "pyclass",
+ "password": getpass(),
+ "device_type": "cisco_ios",
+}
+
+net_connect = Netmiko(**cisco1)
+print(net_connect.find_prompt())
+net_connect.write_channel("show ip int brief\n")
+time.sleep(1)
+output = net_connect.read_channel()
+print(output)
+net_connect.disconnect()
diff --git a/images/netmiko_logo_gh.png b/images/netmiko_logo_gh.png
new file mode 100644
index 000000000..7ffcf67c9
Binary files /dev/null and b/images/netmiko_logo_gh.png differ
diff --git a/license-dependencies.txt b/license-dependencies.txt
new file mode 100644
index 000000000..4f815244c
--- /dev/null
+++ b/license-dependencies.txt
@@ -0,0 +1,29 @@
+#### Netmiko dependencies
+#### 2021-05-31
+
+Name Version License
+------------- ------- -------
+netmiko 3.4.0 MIT License
+
+##### Direct dependencies
+Name Version License
+------------- ------- -------
+paramiko 2.7.2 GNU Library or Lesser General Public License (LGPL)
+scp 0.13.3 GNU Library or Lesser General Public License (LGPL)
+tenacity 7.0.0 Apache Software License
+ntc-templates 2.0.0 Apache Software License
+pyserial 3.5 BSD License
+
+##### Child dependencies
+Name Version License
+------------- ------- -------
+PyNaCl 1.4.0 Apache License 2.0
+bcrypt 3.2.0 Apache Software License
+textfsm 1.1.0 Apache Software License
+cryptography 3.4.7 Apache Software License, BSD License
+pycparser 2.20 BSD License
+cffi 1.14.5 MIT License
+future 0.18.2 MIT License
+six 1.16.0 MIT License
+
+With assistance from `pip-licenses -o license`
diff --git a/mypy_status.txt b/mypy_status.txt
new file mode 100644
index 000000000..7069853f9
--- /dev/null
+++ b/mypy_status.txt
@@ -0,0 +1,16 @@
+# mypy ./netmiko/base_connection.py
+2021-06-01 Found 1896 errors in 93 files (checked 1 source file)
+2021-06-03 Found 1882 errors in 94 files (checked 1 source file)
+2021-06-04 Found 1755 errors in 94 files (checked 1 source file)
+2021-06-06 Found 1657 errors in 94 files (checked 1 source file)
+2021-06-19 Found 1052 errors in 94 files (checked 1 source file)
+# Upgraded to mypy 0.902
+# mypy ./netmiko
+2021-06-22 Found 852 errors in 90 files (checked 171 source files)
+2021-06-23 Found 841 errors in 89 files (checked 171 source files)
+2021-06-26 Found 627 errors in 67 files (checked 171 source files)
+2021-06-27 Found 539 errors in 59 files (checked 171 source files)
+2021-06-29 Found 483 errors in 53 files (checked 171 source files)
+2021-07-01 Found 430 errors in 46 files (checked 171 source files)
+2021-07-08 Found 402 errors in 39 files (checked 171 source files)
+2021-07-20 Success: no issues found in 171 source files
diff --git a/netmiko/__init__.py b/netmiko/__init__.py
index f2f600d9c..76928a7a1 100644
--- a/netmiko/__init__.py
+++ b/netmiko/__init__.py
@@ -1,33 +1,62 @@
-from __future__ import unicode_literals
import logging
# Logging configuration
-log = logging.getLogger(__name__) # noqa
-log.addHandler(logging.NullHandler()) # noqa
+log = logging.getLogger(__name__) # noqa
+log.addHandler(logging.NullHandler()) # noqa
from netmiko.ssh_dispatcher import ConnectHandler
+from netmiko.ssh_dispatcher import ConnLogOnly
+from netmiko.ssh_dispatcher import ConnUnify
from netmiko.ssh_dispatcher import ssh_dispatcher
from netmiko.ssh_dispatcher import redispatch
from netmiko.ssh_dispatcher import platforms
from netmiko.ssh_dispatcher import FileTransfer
from netmiko.scp_handler import SCPConn
from netmiko.cisco.cisco_ios import InLineTransfer
-from netmiko.ssh_exception import NetMikoTimeoutException
-from netmiko.ssh_exception import NetMikoAuthenticationException
+from netmiko.exceptions import (
+ NetmikoTimeoutException,
+ NetMikoTimeoutException,
+)
+from netmiko.exceptions import (
+ NetmikoAuthenticationException,
+ NetMikoAuthenticationException,
+)
+from netmiko.exceptions import ConfigInvalidException
+from netmiko.exceptions import ReadException, ReadTimeout
+from netmiko.exceptions import NetmikoBaseException, ConnectionException
from netmiko.ssh_autodetect import SSHDetect
from netmiko.base_connection import BaseConnection
-from netmiko.scp_functions import file_transfer
+from netmiko.scp_functions import file_transfer, progress_bar
# Alternate naming
-NetmikoTimeoutError = NetMikoTimeoutException
-NetmikoAuthError = NetMikoAuthenticationException
Netmiko = ConnectHandler
-__version__ = '2.1.1'
-__all__ = ('ConnectHandler', 'ssh_dispatcher', 'platforms', 'SCPConn', 'FileTransfer',
- 'NetMikoTimeoutException', 'NetMikoAuthenticationException',
- 'NetmikoTimeoutError', 'NetmikoAuthError', 'InLineTransfer', 'redispatch',
- 'SSHDetect', 'BaseConnection', 'Netmiko', 'file_transfer')
+__version__ = "4.0.0"
+__all__ = (
+ "ConnectHandler",
+ "ConnLogOnly",
+ "ConnUnify",
+ "ssh_dispatcher",
+ "platforms",
+ "SCPConn",
+ "FileTransfer",
+ "NetmikoBaseException",
+ "ConnectionException",
+ "NetmikoTimeoutException",
+ "NetMikoTimeoutException",
+ "ConfigInvalidException",
+ "ReadException",
+ "ReadTimeout",
+ "NetmikoAuthenticationException",
+ "NetMikoAuthenticationException",
+ "InLineTransfer",
+ "redispatch",
+ "SSHDetect",
+ "BaseConnection",
+ "Netmiko",
+ "file_transfer",
+ "progress_bar",
+)
# Cisco cntl-shift-six sequence
CNTL_SHIFT_6 = chr(30)
diff --git a/netmiko/_textfsm/__init__.py b/netmiko/_textfsm/__init__.py
deleted file mode 100644
index a9af36bc8..000000000
--- a/netmiko/_textfsm/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from netmiko._textfsm import _terminal
-from netmiko._textfsm import _texttable
-from netmiko._textfsm import _clitable
-
-__all__ = ('_terminal', '_texttable', '_clitable')
diff --git a/netmiko/_textfsm/_clitable.py b/netmiko/_textfsm/_clitable.py
deleted file mode 100644
index 20286f995..000000000
--- a/netmiko/_textfsm/_clitable.py
+++ /dev/null
@@ -1,380 +0,0 @@
-"""
-Google's clitable.py is inherently integrated to Linux:
-
-This is a workaround for that (basically include modified clitable code without anything
-that is Linux-specific).
-
-_clitable.py is identical to Google's as of 2017-12-17
-_texttable.py is identical to Google's as of 2017-12-17
-_terminal.py is a highly stripped down version of Google's such that clitable.py works
-
-https://github.com/google/textfsm/blob/master/clitable.py
-"""
-
-# Some of this code is from Google with the following license:
-#
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-import copy
-import os
-import re
-import threading
-import copyable_regex_object
-import textfsm
-from netmiko._textfsm import _texttable as texttable
-
-
-class Error(Exception):
- """Base class for errors."""
-
-
-class IndexTableError(Error):
- """General INdexTable error."""
-
-
-class CliTableError(Error):
- """General CliTable error."""
-
-
-class IndexTable(object):
- """Class that reads and stores comma-separated values as a TextTable.
- Stores a compiled regexp of the value for efficient matching.
- Includes functions to preprocess Columns (both compiled and uncompiled).
- Attributes:
- index: TextTable, the index file parsed into a texttable.
- compiled: TextTable, the table but with compiled regexp for each field.
- """
-
- def __init__(self, preread=None, precompile=None, file_path=None):
- """Create new IndexTable object.
- Args:
- preread: func, Pre-processing, applied to each field as it is read.
- precompile: func, Pre-compilation, applied to each field before compiling.
- file_path: String, Location of file to use as input.
- """
- self.index = None
- self.compiled = None
- if file_path:
- self._index_file = file_path
- self._index_handle = open(self._index_file, 'r')
- self._ParseIndex(preread, precompile)
-
- def __del__(self):
- """Close index handle."""
- if hasattr(self, '_index_handle'):
- self._index_handle.close()
-
- def __len__(self):
- """Returns number of rows in table."""
- return self.index.size
-
- def __copy__(self):
- """Returns a copy of an IndexTable object."""
- clone = IndexTable()
- if hasattr(self, '_index_file'):
- # pylint: disable=protected-access
- clone._index_file = self._index_file
- clone._index_handle = self._index_handle
-
- clone.index = self.index
- clone.compiled = self.compiled
- return clone
-
- def __deepcopy__(self, memodict=None):
- """Returns a deepcopy of an IndexTable object."""
- clone = IndexTable()
- if hasattr(self, '_index_file'):
- # pylint: disable=protected-access
- clone._index_file = copy.deepcopy(self._index_file)
- clone._index_handle = open(clone._index_file, 'r')
-
- clone.index = copy.deepcopy(self.index)
- clone.compiled = copy.deepcopy(self.compiled)
- return clone
-
- def _ParseIndex(self, preread, precompile):
- """Reads index file and stores entries in TextTable.
- For optimisation reasons, a second table is created with compiled entries.
- Args:
- preread: func, Pre-processing, applied to each field as it is read.
- precompile: func, Pre-compilation, applied to each field before compiling.
- Raises:
- IndexTableError: If the column headers has illegal column labels.
- """
- self.index = texttable.TextTable()
- self.index.CsvToTable(self._index_handle)
-
- if preread:
- for row in self.index:
- for col in row.header:
- row[col] = preread(col, row[col])
-
- self.compiled = copy.deepcopy(self.index)
-
- for row in self.compiled:
- for col in row.header:
- if precompile:
- row[col] = precompile(col, row[col])
- if row[col]:
- row[col] = copyable_regex_object.CopyableRegexObject(row[col])
-
- def GetRowMatch(self, attributes):
- """Returns the row number that matches the supplied attributes."""
- for row in self.compiled:
- try:
- for key in attributes:
- # Silently skip attributes not present in the index file.
- # pylint: disable=E1103
- if key in row.header and row[key] and not row[key].match(attributes[key]):
- # This line does not match, so break and try next row.
- raise StopIteration()
- return row.row
- except StopIteration:
- pass
- return 0
-
-
-class CliTable(texttable.TextTable):
- """Class that reads CLI output and parses into tabular format.
- Reads an index file and uses it to map command strings to templates. It then
- uses TextFSM to parse the command output (raw) into a tabular format.
- The superkey is the set of columns that contain data that uniquely defines the
- row, the key is the row number otherwise. This is typically gathered from the
- templates 'Key' value but is extensible.
- Attributes:
- raw: String, Unparsed command string from device/command.
- index_file: String, file where template/command mappings reside.
- template_dir: String, directory where index file and templates reside.
- """
-
- # Parse each template index only once across all instances.
- # Without this, the regexes are parsed at every call to CliTable().
- _lock = threading.Lock()
- INDEX = {}
-
- # pylint: disable=C6409
- def synchronised(func):
- """Synchronisation decorator."""
-
- # pylint: disable=E0213
- def Wrapper(main_obj, *args, **kwargs):
- main_obj._lock.acquire() # pylint: disable=W0212
- try:
- return func(main_obj, *args, **kwargs) # pylint: disable=E1102
- finally:
- main_obj._lock.release() # pylint: disable=W0212
- return Wrapper
- # pylint: enable=C6409
-
- @synchronised
- def __init__(self, index_file=None, template_dir=None):
- """Create new CLiTable object.
- Args:
- index_file: String, file where template/command mappings reside.
- template_dir: String, directory where index file and templates reside.
- """
- # pylint: disable=E1002
- super(CliTable, self).__init__()
- self._keys = set()
- self.raw = None
- self.index_file = index_file
- self.template_dir = template_dir
- if index_file:
- self.ReadIndex(index_file)
-
- def ReadIndex(self, index_file=None):
- """Reads the IndexTable index file of commands and templates.
- Args:
- index_file: String, file where template/command mappings reside.
- Raises:
- CliTableError: A template column was not found in the table.
- """
-
- self.index_file = index_file or self.index_file
- fullpath = os.path.join(self.template_dir, self.index_file)
- if self.index_file and fullpath not in self.INDEX:
- self.index = IndexTable(self._PreParse, self._PreCompile, fullpath)
- self.INDEX[fullpath] = self.index
- else:
- self.index = self.INDEX[fullpath]
-
- # Does the IndexTable have the right columns.
- if 'Template' not in self.index.index.header: # pylint: disable=E1103
- raise CliTableError("Index file does not have 'Template' column.")
-
- def _TemplateNamesToFiles(self, template_str):
- """Parses a string of templates into a list of file handles."""
- template_list = template_str.split(':')
- template_files = []
- try:
- for tmplt in template_list:
- template_files.append(
- open(os.path.join(self.template_dir, tmplt), 'r'))
- except: # noqa
- for tmplt in template_files:
- tmplt.close()
- raise
-
- return template_files
-
- def ParseCmd(self, cmd_input, attributes=None, templates=None):
- """Creates a TextTable table of values from cmd_input string.
- Parses command output with template/s. If more than one template is found
- subsequent tables are merged if keys match (dropped otherwise).
- Args:
- cmd_input: String, Device/command response.
- attributes: Dict, attribute that further refine matching template.
- templates: String list of templates to parse with. If None, uses index
- Raises:
- CliTableError: A template was not found for the given command.
- """
- # Store raw command data within the object.
- self.raw = cmd_input
-
- if not templates:
- # Find template in template index.
- row_idx = self.index.GetRowMatch(attributes)
- if row_idx:
- templates = self.index.index[row_idx]['Template']
- else:
- raise CliTableError('No template found for attributes: "%s"' %
- attributes)
-
- template_files = self._TemplateNamesToFiles(templates)
-
- try:
- # Re-initialise the table.
- self.Reset()
- self._keys = set()
- self.table = self._ParseCmdItem(self.raw, template_file=template_files[0])
-
- # Add additional columns from any additional tables.
- for tmplt in template_files[1:]:
- self.extend(self._ParseCmdItem(self.raw, template_file=tmplt),
- set(self._keys))
- finally:
- for f in template_files:
- f.close()
-
- def _ParseCmdItem(self, cmd_input, template_file=None):
- """Creates Texttable with output of command.
- Args:
- cmd_input: String, Device response.
- template_file: File object, template to parse with.
- Returns:
- TextTable containing command output.
- Raises:
- CliTableError: A template was not found for the given command.
- """
- # Build FSM machine from the template.
- fsm = textfsm.TextFSM(template_file)
- if not self._keys:
- self._keys = set(fsm.GetValuesByAttrib('Key'))
-
- # Pass raw data through FSM.
- table = texttable.TextTable()
- table.header = fsm.header
-
- # Fill TextTable from record entries.
- for record in fsm.ParseText(cmd_input):
- table.Append(record)
- return table
-
- def _PreParse(self, key, value):
- """Executed against each field of each row read from index table."""
- if key == 'Command':
- return re.sub(r'(\[\[.+?\]\])', self._Completion, value)
- else:
- return value
-
- def _PreCompile(self, key, value):
- """Executed against each field of each row before compiling as regexp."""
- if key == 'Template':
- return
- else:
- return value
-
- def _Completion(self, match):
- # pylint: disable=C6114
- r"""Replaces double square brackets with variable length completion.
- Completion cannot be mixed with regexp matching or '\' characters
- i.e. '[[(\n)]] would become (\(n)?)?.'
- Args:
- match: A regex Match() object.
- Returns:
- String of the format '(a(b(c(d)?)?)?)?'.
- """
- # Strip the outer '[[' & ']]' and replace with ()? regexp pattern.
- word = str(match.group())[2:-2]
- return '(' + ('(').join(word) + ')?' * len(word)
-
- def LabelValueTable(self, keys=None):
- """Return LabelValue with FSM derived keys."""
- keys = keys or self.superkey
- # pylint: disable=E1002
- return super(CliTable, self).LabelValueTable(keys)
-
- # pylint: disable=W0622,C6409
- def sort(self, cmp=None, key=None, reverse=False):
- """Overrides sort func to use the KeyValue for the key."""
- if not key and self._keys:
- key = self.KeyValue
- super(CliTable, self).sort(cmp=cmp, key=key, reverse=reverse)
- # pylint: enable=W0622
-
- def AddKeys(self, key_list):
- """Mark additional columns as being part of the superkey.
- Supplements the Keys already extracted from the FSM template.
- Useful when adding new columns to existing tables.
- Note: This will impact attempts to further 'extend' the table as the
- superkey must be common between tables for successful extension.
- Args:
- key_list: list of header entries to be included in the superkey.
- Raises:
- KeyError: If any entry in list is not a valid header entry.
- """
-
- for keyname in key_list:
- if keyname not in self.header:
- raise KeyError("'%s'" % keyname)
-
- self._keys = self._keys.union(set(key_list))
-
- @property
- def superkey(self):
- """Returns a set of column names that together constitute the superkey."""
- sorted_list = []
- for header in self.header:
- if header in self._keys:
- sorted_list.append(header)
- return sorted_list
-
- def KeyValue(self, row=None):
- """Returns the super key value for the row."""
- if not row:
- if self._iterator:
- # If we are inside an iterator use current row iteration.
- row = self[self._iterator]
- else:
- row = self.row
- # If no superkey then use row number.
- if not self.superkey:
- return ['%s' % row.row]
-
- sorted_list = []
- for header in self.header:
- if header in self.superkey:
- sorted_list.append(row[header])
- return sorted_list
diff --git a/netmiko/_textfsm/_terminal.py b/netmiko/_textfsm/_terminal.py
deleted file mode 100644
index c94eb8997..000000000
--- a/netmiko/_textfsm/_terminal.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
-Google's clitable.py is inherently integrated to Linux.
-
-This is a workaround for that (basically include modified clitable code without anything
-that is Linux-specific).
-
-_clitable.py is identical to Google's as of 2017-12-17
-_texttable.py is identical to Google's as of 2017-12-17
-_terminal.py is a highly stripped down version of Google's such that clitable.py works
-
-https://github.com/google/textfsm/blob/master/clitable.py
-"""
-
-# Some of this code is from Google with the following license:
-#
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import re
-
-
-__version__ = '0.1.1'
-
-
-# ANSI, ISO/IEC 6429 escape sequences, SGR (Select Graphic Rendition) subset.
-SGR = {
- 'reset': 0,
- 'bold': 1,
- 'underline': 4,
- 'blink': 5,
- 'negative': 7,
- 'underline_off': 24,
- 'blink_off': 25,
- 'positive': 27,
- 'black': 30,
- 'red': 31,
- 'green': 32,
- 'yellow': 33,
- 'blue': 34,
- 'magenta': 35,
- 'cyan': 36,
- 'white': 37,
- 'fg_reset': 39,
- 'bg_black': 40,
- 'bg_red': 41,
- 'bg_green': 42,
- 'bg_yellow': 43,
- 'bg_blue': 44,
- 'bg_magenta': 45,
- 'bg_cyan': 46,
- 'bg_white': 47,
- 'bg_reset': 49,
- }
-
-# Provide a familar descriptive word for some ansi sequences.
-FG_COLOR_WORDS = {'black': ['black'],
- 'dark_gray': ['bold', 'black'],
- 'blue': ['blue'],
- 'light_blue': ['bold', 'blue'],
- 'green': ['green'],
- 'light_green': ['bold', 'green'],
- 'cyan': ['cyan'],
- 'light_cyan': ['bold', 'cyan'],
- 'red': ['red'],
- 'light_red': ['bold', 'red'],
- 'purple': ['magenta'],
- 'light_purple': ['bold', 'magenta'],
- 'brown': ['yellow'],
- 'yellow': ['bold', 'yellow'],
- 'light_gray': ['white'],
- 'white': ['bold', 'white']}
-
-BG_COLOR_WORDS = {'black': ['bg_black'],
- 'red': ['bg_red'],
- 'green': ['bg_green'],
- 'yellow': ['bg_yellow'],
- 'dark_blue': ['bg_blue'],
- 'purple': ['bg_magenta'],
- 'light_blue': ['bg_cyan'],
- 'grey': ['bg_white']}
-
-
-# Characters inserted at the start and end of ANSI strings
-# to provide hinting for readline and other clients.
-ANSI_START = '\001'
-ANSI_END = '\002'
-
-
-sgr_re = re.compile(r'(%s?\033\[\d+(?:;\d+)*m%s?)' % (
- ANSI_START, ANSI_END))
-
-
-def StripAnsiText(text):
- """Strip ANSI/SGR escape sequences from text."""
- return sgr_re.sub('', text)
diff --git a/netmiko/_textfsm/_texttable.py b/netmiko/_textfsm/_texttable.py
deleted file mode 100644
index 1202b34de..000000000
--- a/netmiko/_textfsm/_texttable.py
+++ /dev/null
@@ -1,1103 +0,0 @@
-"""
-Google's clitable.py is inherently integrated to Linux:
-
-This is a workaround for that (basically include modified clitable code without anything
-that is Linux-specific).
-
-_clitable.py is identical to Google's as of 2017-12-17
-_texttable.py is identical to Google's as of 2017-12-17
-_terminal.py is a highly stripped down version of Google's such that clitable.py works
-
-https://github.com/google/textfsm/blob/master/clitable.py
-
-A module to represent and manipulate tabular text data.
-
-A table of rows, indexed on row number. Each row is a ordered dictionary of row
-elements that maintains knowledge of the parent table and column headings.
-
-Tables can be created from CSV input and in-turn supports a number of display
-formats such as CSV and variable sized and justified rows.
-"""
-
-# Some of this code is from Google with the following license:
-#
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-import copy
-from functools import cmp_to_key
-import textwrap
-# pylint: disable=redefined-builtin
-from six.moves import range
-from netmiko._textfsm import _terminal as terminal
-
-
-class Error(Exception):
- """Base class for errors."""
-
-
-class TableError(Error):
- """Error in TextTable."""
-
-
-class Row(dict):
- """Represents a table row. We implement this as an ordered dictionary.
-
- The order is the chronological order of data insertion. Methods are supplied
- to make it behave like a regular dict() and list().
-
- Attributes:
- row: int, the row number in the container table. 0 is the header row.
- table: A TextTable(), the associated container table.
- """
-
- def __init__(self, *args, **kwargs):
- super(Row, self).__init__(*args, **kwargs)
- self._keys = list()
- self._values = list()
- self.row = None
- self.table = None
- self._color = None
- self._index = {}
-
- def _BuildIndex(self):
- """Recreate the key index."""
- self._index = {}
- for i, k in enumerate(self._keys):
- self._index[k] = i
-
- def __getitem__(self, column):
- """Support for [] notation.
-
- Args:
- column: Tuple of column names, or a (str) column name, or positional
- column number, 0-indexed.
-
- Returns:
- A list or string with column value(s).
-
- Raises:
- IndexError: The given column(s) were not found.
- """
- if isinstance(column, (list, tuple)):
- ret = []
- for col in column:
- ret.append(self[col])
- return ret
-
- try:
- return self._values[self._index[column]]
- except (KeyError, TypeError, ValueError):
- pass
-
- # Perhaps we have a range like '1', ':-1' or '1:'.
- try:
- return self._values[column]
- except (IndexError, TypeError):
- pass
-
- raise IndexError('No such column "%s" in row.' % column)
-
- def __contains__(self, value):
- return value in self._values
-
- def __setitem__(self, column, value):
- for i in range(len(self)):
- if self._keys[i] == column:
- self._values[i] = value
- return
- # No column found, add a new one.
- self._keys.append(column)
- self._values.append(value)
- self._BuildIndex()
-
- def __iter__(self):
- return iter(self._values)
-
- def __len__(self):
- return len(self._keys)
-
- def __str__(self):
- ret = ''
- for v in self._values:
- ret += '%12s ' % v
- ret += '\n'
- return ret
-
- def __repr__(self):
- return '%s(%r)' % (self.__class__.__name__, str(self))
-
- def get(self, column, default_value=None):
- """Get an item from the Row by column name.
-
- Args:
- column: Tuple of column names, or a (str) column name, or positional
- column number, 0-indexed.
- default_value: The value to use if the key is not found.
-
- Returns:
- A list or string with column value(s) or default_value if not found.
- """
- if isinstance(column, (list, tuple)):
- ret = []
- for col in column:
- ret.append(self.get(col, default_value))
- return ret
- # Perhaps we have a range like '1', ':-1' or '1:'.
- try:
- return self._values[column]
- except (IndexError, TypeError):
- pass
- try:
- return self[column]
- except IndexError:
- return default_value
-
- def index(self, column): # pylint: disable=C6409
- """Fetches the column number (0 indexed).
-
- Args:
- column: A string, column to fetch the index of.
-
- Returns:
- An int, the row index number.
-
- Raises:
- ValueError: The specified column was not found.
- """
- for i, key in enumerate(self._keys):
- if key == column:
- return i
- raise ValueError('Column "%s" not found.' % column)
-
- def iterkeys(self):
- return iter(self._keys)
-
- def items(self):
- # TODO(harro): self.get(k) should work here but didn't ?
- return [(k, self.__getitem__(k)) for k in self._keys]
-
- def _GetValues(self):
- """Return the row's values."""
- return self._values
-
- def _GetHeader(self):
- """Return the row's header."""
- return self._keys
-
- def _SetHeader(self, values):
- """Set the row's header from a list."""
- if self._values and len(values) != len(self._values):
- raise ValueError('Header values not equal to existing data width.')
- if not self._values:
- for _ in range(len(values)):
- self._values.append(None)
- self._keys = list(values)
- self._BuildIndex()
-
- def _SetColour(self, value_list):
- """Sets row's colour attributes to a list of values in terminal.SGR."""
- if value_list is None:
- self._color = None
- return
- colors = []
- for color in value_list:
- if color in terminal.SGR:
- colors.append(color)
- elif color in terminal.FG_COLOR_WORDS:
- colors += terminal.FG_COLOR_WORDS[color]
- elif color in terminal.BG_COLOR_WORDS:
- colors += terminal.BG_COLOR_WORDS[color]
- else:
- raise ValueError('Invalid colour specification.')
- self._color = list(set(colors))
-
- def _GetColour(self):
- if self._color is None:
- return None
- return list(self._color)
-
- def _SetValues(self, values):
- """Set values from supplied dictionary or list.
-
- Args:
- values: A Row, dict indexed by column name, or list.
-
- Raises:
- TypeError: Argument is not a list or dict, or list is not equal row
- length or dictionary keys don't match.
- """
-
- def _ToStr(value):
- """Convert individul list entries to string."""
- if isinstance(value, (list, tuple)):
- result = []
- for val in value:
- result.append(str(val))
- return result
- else:
- return str(value)
-
- # Row with identical header can be copied directly.
- if isinstance(values, Row):
- if self._keys != values.header:
- raise TypeError('Attempt to append row with mismatched header.')
- self._values = copy.deepcopy(values.values)
-
- elif isinstance(values, dict):
- for key in self._keys:
- if key not in values:
- raise TypeError('Dictionary key mismatch with row.')
- for key in self._keys:
- self[key] = _ToStr(values[key])
-
- elif isinstance(values, list) or isinstance(values, tuple):
- if len(values) != len(self._values):
- raise TypeError('Supplied list length != row length')
- for (index, value) in enumerate(values):
- self._values[index] = _ToStr(value)
-
- else:
- raise TypeError('Supplied argument must be Row, dict or list, not %s',
- type(values))
-
- def Insert(self, key, value, row_index):
- """Inserts new values at a specified offset.
-
- Args:
- key: string for header value.
- value: string for a data value.
- row_index: Offset into row for data.
-
- Raises:
- IndexError: If the offset is out of bands.
- """
- if row_index < 0:
- row_index += len(self)
-
- if not 0 <= row_index < len(self):
- raise IndexError('Index "%s" is out of bounds.' % row_index)
-
- new_row = Row()
- for idx in self.header:
- if self.index(idx) == row_index:
- new_row[key] = value
- new_row[idx] = self[idx]
- self._keys = new_row.header
- self._values = new_row.values
- del new_row
- self._BuildIndex()
-
- color = property(_GetColour, _SetColour, doc='Colour spec of this row')
- header = property(_GetHeader, _SetHeader, doc="List of row's headers.")
- values = property(_GetValues, _SetValues, doc="List of row's values.")
-
-
-class TextTable(object):
- """Class that provides data methods on a tabular format.
-
- Data is stored as a list of Row() objects. The first row is always present as
- the header row.
-
- Attributes:
- row_class: class, A class to use for the Row object.
- separator: str, field separator when printing table.
- """
-
- def __init__(self, row_class=Row):
- """Initialises a new table.
-
- Args:
- row_class: A class to use as the row object. This should be a
- subclass of this module's Row() class.
- """
- self.row_class = row_class
- self.separator = ', '
- self.Reset()
-
- def Reset(self):
- self._row_index = 1
- self._table = [[]]
- self._iterator = 0 # While loop row index
-
- def __repr__(self):
- return '%s(%r)' % (self.__class__.__name__, str(self))
-
- def __str__(self):
- """Displays table with pretty formatting."""
- return self.table
-
- def __incr__(self, incr=1):
- self._SetRowIndex(self._row_index + incr)
-
- def __contains__(self, name):
- """Whether the given column header name exists."""
- return name in self.header
-
- def __getitem__(self, row):
- """Fetches the given row number."""
- return self._table[row]
-
- def __iter__(self):
- """Iterator that excludes the header row."""
- return self.next()
-
- def next(self):
- # Maintain a counter so a row can know what index it is.
- # Save the old value to support nested interations.
- old_iter = self._iterator
- try:
- for r in self._table[1:]:
- self._iterator = r.row
- yield r
- finally:
- # Recover the original index after loop termination or exit with break.
- self._iterator = old_iter
-
- def __add__(self, other):
- """Merges two with identical columns."""
-
- new_table = copy.copy(self)
- for row in other:
- new_table.Append(row)
-
- return new_table
-
- def __copy__(self):
- """Copy table instance."""
-
- new_table = self.__class__()
- # pylint: disable=protected-access
- new_table._table = [self.header]
- for row in self[1:]:
- new_table.Append(row)
- return new_table
-
- def Filter(self, function=None):
- """Construct Textable from the rows of which the function returns true.
-
-
- Args:
- function: A function applied to each row which returns a bool. If
- function is None, all rows with empty column values are
- removed.
- Returns:
- A new TextTable()
-
- Raises:
- TableError: When an invalid row entry is Append()'d
- """
- flat = lambda x: x if isinstance(x, str) else ''.join([flat(y) for y in x]) # noqa
- if function is None:
- function = lambda row: bool(flat(row.values)) # noqa
-
- new_table = self.__class__()
- # pylint: disable=protected-access
- new_table._table = [self.header]
- for row in self:
- if function(row) is True:
- new_table.Append(row)
- return new_table
-
- def Map(self, function):
- """Applies the function to every row in the table.
-
- Args:
- function: A function applied to each row.
-
- Returns:
- A new TextTable()
-
- Raises:
- TableError: When transform is not invalid row entry. The transform
- must be compatible with Append().
- """
- new_table = self.__class__()
- # pylint: disable=protected-access
- new_table._table = [self.header]
- for row in self:
- filtered_row = function(row)
- if filtered_row:
- new_table.Append(filtered_row)
- return new_table
-
- # pylint: disable=C6409
- # pylint: disable=W0622
- def sort(self, cmp=None, key=None, reverse=False):
- """Sorts rows in the texttable.
-
- Args:
- cmp: func, non default sort algorithm to use.
- key: func, applied to each element before sorting.
- reverse: bool, reverse order of sort.
- """
-
- def _DefaultKey(value):
- """Default key func is to create a list of all fields."""
- result = []
- for key in self.header:
- # Try sorting as numerical value if possible.
- try:
- result.append(float(value[key]))
- except ValueError:
- result.append(value[key])
- return result
-
- key = key or _DefaultKey
- # Exclude header by copying table.
- new_table = self._table[1:]
-
- if cmp is not None:
- key = cmp_to_key(cmp)
-
- new_table.sort(key=key, reverse=reverse)
-
- # Regenerate the table with original header
- self._table = [self.header]
- self._table.extend(new_table)
- # Re-write the 'row' attribute of each row
- for index, row in enumerate(self._table):
- row.row = index
- # pylint: enable=W0622
-
- def extend(self, table, keys=None):
- """Extends all rows in the texttable.
-
- The rows are extended with the new columns from the table.
-
- Args:
- table: A texttable, the table to extend this table by.
- keys: A set, the set of columns to use as the key. If None, the
- row index is used.
-
- Raises:
- IndexError: If key is not a valid column name.
- """
- if keys:
- for k in keys:
- if k not in self._Header():
- raise IndexError("Unknown key: '%s'", k)
-
- extend_with = []
- for column in table.header:
- if column not in self.header:
- extend_with.append(column)
-
- if not extend_with:
- return
-
- for column in extend_with:
- self.AddColumn(column)
-
- if not keys:
- for row1, row2 in zip(self, table):
- for column in extend_with:
- row1[column] = row2[column]
- return
-
- for row1 in self:
- for row2 in table:
- for k in keys:
- if row1[k] != row2[k]:
- break
- else:
- for column in extend_with:
- row1[column] = row2[column]
- break
-
- # pylint: enable=C6409
- def Remove(self, row):
- """Removes a row from the table.
-
- Args:
- row: int, the row number to delete. Must be >= 1, as the header
- cannot be removed.
-
- Raises:
- TableError: Attempt to remove nonexistent or header row.
- """
- if row == 0 or row > self.size:
- raise TableError('Attempt to remove header row')
- new_table = []
- # pylint: disable=E1103
- for t_row in self._table:
- if t_row.row != row:
- new_table.append(t_row)
- if t_row.row > row:
- t_row.row -= 1
- self._table = new_table
-
- def _Header(self):
- """Returns the header row."""
- return self._table[0]
-
- def _GetRow(self, columns=None):
- """Returns the current row as a tuple."""
-
- row = self._table[self._row_index]
- if columns:
- result = []
- for col in columns:
- if col not in self.header:
- raise TableError('Column header %s not known in table.' % col)
- result.append(row[self.header.index(col)])
- row = result
- return row
-
- def _SetRow(self, new_values, row=0):
- """Sets the current row to new list.
-
- Args:
- new_values: List|dict of new values to insert into row.
- row: int, Row to insert values into.
-
- Raises:
- TableError: If number of new values is not equal to row size.
- """
-
- if not row:
- row = self._row_index
-
- if row > self.size:
- raise TableError('Entry %s beyond table size %s.' % (row, self.size))
-
- self._table[row].values = new_values
-
- def _SetHeader(self, new_values):
- """Sets header of table to the given tuple.
-
- Args:
- new_values: Tuple of new header values.
- """
- row = self.row_class()
- row.row = 0
- for v in new_values:
- row[v] = v
- self._table[0] = row
-
- def _SetRowIndex(self, row):
- if not row or row > self.size:
- raise TableError('Entry %s beyond table size %s.' % (row, self.size))
- self._row_index = row
-
- def _GetRowIndex(self):
- return self._row_index
-
- def _GetSize(self):
- """Returns number of rows in table."""
-
- if not self._table:
- return 0
- return len(self._table) - 1
-
- def _GetTable(self):
- """Returns table, with column headers and separators.
-
- Returns:
- The whole table including headers as a string. Each row is
- joined by a newline and each entry by self.separator.
- """
- result = []
- # Avoid the global lookup cost on each iteration.
- lstr = str
- for row in self._table:
- result.append(
- '%s\n' %
- self.separator.join(lstr(v) for v in row))
-
- return ''.join(result)
-
- def _SetTable(self, table):
- """Sets table, with column headers and separators."""
- if not isinstance(table, TextTable):
- raise TypeError('Not an instance of TextTable.')
- self.Reset()
- self._table = copy.deepcopy(table._table) # pylint: disable=W0212
- # Point parent table of each row back ourselves.
- for row in self:
- row.table = self
-
- def _SmallestColSize(self, text):
- """Finds the largest indivisible word of a string.
-
- ...and thus the smallest possible column width that can contain that
- word unsplit over rows.
-
- Args:
- text: A string of text potentially consisting of words.
-
- Returns:
- Integer size of the largest single word in the text.
- """
- if not text:
- return 0
- stripped = terminal.StripAnsiText(text)
- return max(len(word) for word in stripped.split())
-
- def _TextJustify(self, text, col_size):
- """Formats text within column with white space padding.
-
- A single space is prefixed, and a number of spaces are added as a
- suffix such that the length of the resultant string equals the col_size.
-
- If the length of the text exceeds the column width available then it
- is split into words and returned as a list of string, each string
- contains one or more words padded to the column size.
-
- Args:
- text: String of text to format.
- col_size: integer size of column to pad out the text to.
-
- Returns:
- List of strings col_size in length.
-
- Raises:
- TableError: If col_size is too small to fit the words in the text.
- """
- result = []
- if '\n' in text:
- for paragraph in text.split('\n'):
- result.extend(self._TextJustify(paragraph, col_size))
- return result
-
- wrapper = textwrap.TextWrapper(width=col_size-2, break_long_words=False,
- expand_tabs=False)
- try:
- text_list = wrapper.wrap(text)
- except ValueError:
- raise TableError('Field too small (minimum width: 3)')
-
- if not text_list:
- return [' '*col_size]
-
- for current_line in text_list:
- stripped_len = len(terminal.StripAnsiText(current_line))
- ansi_color_adds = len(current_line) - stripped_len
- # +2 for white space on either side.
- if stripped_len + 2 > col_size:
- raise TableError('String contains words that do not fit in column.')
-
- result.append(' %-*s' % (col_size - 1 + ansi_color_adds, current_line))
-
- return result
-
- def FormattedTable(self, width=80, force_display=False, ml_delimiter=True,
- color=True, display_header=True, columns=None):
- """Returns whole table, with whitespace padding and row delimiters.
-
- Args:
- width: An int, the max width we want the table to fit in.
- force_display: A bool, if set to True will display table when the table
- can't be made to fit to the width.
- ml_delimiter: A bool, if set to False will not display the multi-line
- delimiter.
- color: A bool. If true, display any colours in row.colour.
- display_header: A bool. If true, display header.
- columns: A list of str, show only columns with these names.
-
- Returns:
- A string. The tabled output.
-
- Raises:
- TableError: Width too narrow to display table.
- """
-
- def _FilteredCols():
- """Returns list of column names to display."""
- if not columns:
- return self._Header().values
- return [col for col in self._Header().values if col in columns]
-
- # Largest is the biggest data entry in a column.
- largest = {}
- # Smallest is the same as above but with linewrap i.e. largest unbroken
- # word in the data stream.
- smallest = {}
- # largest == smallest for a column with a single word of data.
- # Initialise largest and smallest for all columns.
- for key in _FilteredCols():
- largest[key] = 0
- smallest[key] = 0
-
- # Find the largest and smallest values.
- # Include Title line in equation.
- # pylint: disable=E1103
- for row in self._table:
- for key, value in row.items():
- if key not in _FilteredCols():
- continue
- # Convert lists into a string.
- if isinstance(value, list):
- value = ', '.join(value)
- value = terminal.StripAnsiText(value)
- largest[key] = max(len(value), largest[key])
- smallest[key] = max(self._SmallestColSize(value), smallest[key])
- # pylint: enable=E1103
-
- min_total_width = 0
- multi_word = []
- # Bump up the size of each column to include minimum pad.
- # Find all columns that can be wrapped (multi-line).
- # And the minimum width needed to display all columns (even if wrapped).
- for key in _FilteredCols():
- # Each column is bracketed by a space on both sides.
- # So increase size required accordingly.
- largest[key] += 2
- smallest[key] += 2
- min_total_width += smallest[key]
- # If column contains data that 'could' be split over multiple lines.
- if largest[key] != smallest[key]:
- multi_word.append(key)
-
- # Check if we have enough space to display the table.
- if min_total_width > width and not force_display:
- raise TableError('Width too narrow to display table.')
-
- # We have some columns that may need wrapping over several lines.
- if multi_word:
- # Find how much space is left over for the wrapped columns to use.
- # Also find how much space we would need if they were not wrapped.
- # These are 'spare_width' and 'desired_width' respectively.
- desired_width = 0
- spare_width = width - min_total_width
- for key in multi_word:
- spare_width += smallest[key]
- desired_width += largest[key]
-
- # Scale up the space we give each wrapped column.
- # Proportional to its size relative to 'desired_width' for all columns.
- # Rinse and repeat if we changed the wrap list in this iteration.
- # Once done we will have a list of columns that definitely need wrapping.
- done = False
- while not done:
- done = True
- for key in multi_word:
- # If we scale past the desired width for this particular column,
- # then give it its desired width and remove it from the wrapped list.
- if (largest[key] <= round((largest[key] / float(desired_width)) * spare_width)):
- smallest[key] = largest[key]
- multi_word.remove(key)
- spare_width -= smallest[key]
- desired_width -= largest[key]
- done = False
- # If we scale below the minimum width for this particular column,
- # then leave it at its minimum and remove it from the wrapped list.
- elif (smallest[key] >=
- round((largest[key] / float(desired_width)) * spare_width)):
- multi_word.remove(key)
- spare_width -= smallest[key]
- desired_width -= largest[key]
- done = False
-
- # Repeat the scaling algorithm with the final wrap list.
- # This time we assign the extra column space by increasing 'smallest'.
- for key in multi_word:
- smallest[key] = int(round((largest[key] / float(desired_width))
- * spare_width))
-
- total_width = 0
- row_count = 0
- result_dict = {}
- # Format the header lines and add to result_dict.
- # Find what the total width will be and use this for the ruled lines.
- # Find how many rows are needed for the most wrapped line (row_count).
- for key in _FilteredCols():
- result_dict[key] = self._TextJustify(key, smallest[key])
- if len(result_dict[key]) > row_count:
- row_count = len(result_dict[key])
- total_width += smallest[key]
-
- # Store header in header_list, working down the wrapped rows.
- header_list = []
- for row_idx in range(row_count):
- for key in _FilteredCols():
- try:
- header_list.append(result_dict[key][row_idx])
- except IndexError:
- # If no value than use whitespace of equal size.
- header_list.append(' '*smallest[key])
- header_list.append('\n')
-
- # Format and store the body lines
- result_dict = {}
- body_list = []
- # We separate multi line rows with a single line delimiter.
- prev_muli_line = False
- # Unless it is the first line in which there is already the header line.
- first_line = True
- for row in self:
- row_count = 0
- for key, value in row.items():
- if key not in _FilteredCols():
- continue
- # Convert field contents to a string.
- if isinstance(value, list):
- value = ', '.join(value)
- # Store results in result_dict and take note of wrapped line count.
- result_dict[key] = self._TextJustify(value, smallest[key])
- if len(result_dict[key]) > row_count:
- row_count = len(result_dict[key])
-
- if row_count > 1:
- prev_muli_line = True
- # If current or prior line was multi-line then include delimiter.
- if not first_line and prev_muli_line and ml_delimiter:
- body_list.append('-'*total_width + '\n')
- if row_count == 1:
- # Our current line was not wrapped, so clear flag.
- prev_muli_line = False
-
- row_list = []
- for row_idx in range(row_count):
- for key in _FilteredCols():
- try:
- row_list.append(result_dict[key][row_idx])
- except IndexError:
- # If no value than use whitespace of equal size.
- row_list.append(' '*smallest[key])
- row_list.append('\n')
-
- if color and row.color is not None:
- # Don't care about colors
- body_list.append(''.join(row_list))
- # body_list.append(
- # terminal.AnsiText(''.join(row_list)[:-1],
- # command_list=row.color))
- # body_list.append('\n')
- else:
- body_list.append(''.join(row_list))
-
- first_line = False
-
- header = ''.join(header_list) + '='*total_width
- if color and self._Header().color is not None:
- pass
- # header = terminal.AnsiText(header, command_list=self._Header().color)
- # Add double line delimiter between header and main body.
- if display_header:
- return '%s\n%s' % (header, ''.join(body_list))
- return '%s' % ''.join(body_list)
-
- def LabelValueTable(self, label_list=None):
- """Returns whole table as rows of name/value pairs.
-
- One (or more) column entries are used for the row prefix label.
- The remaining columns are each displayed as a row entry with the
- prefix labels appended.
-
- Use the first column as the label if label_list is None.
-
- Args:
- label_list: A list of prefix labels to use.
-
- Returns:
- Label/Value formatted table.
-
- Raises:
- TableError: If specified label is not a column header of the table.
- """
- label_list = label_list or self._Header()[0]
- # Ensure all labels are valid.
- for label in label_list:
- if label not in self._Header():
- raise TableError('Invalid label prefix: %s.' % label)
-
- sorted_list = []
- for header in self._Header():
- if header in label_list:
- sorted_list.append(header)
-
- label_str = '# LABEL %s\n' % '.'.join(sorted_list)
-
- body = []
- for row in self:
- # Some of the row values are pulled into the label, stored in label_prefix.
- label_prefix = []
- value_list = []
- for key, value in row.items():
- if key in sorted_list:
- # Set prefix.
- label_prefix.append(value)
- else:
- value_list.append('%s %s' % (key, value))
-
- body.append(''.join(
- ['%s.%s\n' % ('.'.join(label_prefix), v) for v in value_list]))
-
- return '%s%s' % (label_str, ''.join(body))
-
- table = property(_GetTable, _SetTable, doc='Whole table')
- row = property(_GetRow, _SetRow, doc='Current row')
- header = property(_Header, _SetHeader, doc='List of header entries.')
- row_index = property(_GetRowIndex, _SetRowIndex, doc='Current row.')
- size = property(_GetSize, doc='Number of rows in table.')
-
- def RowWith(self, column, value):
- """Retrieves the first non header row with the column of the given value.
-
- Args:
- column: str, the name of the column to check.
- value: str, The value of the column to check.
-
- Returns:
- A Row() of the first row found, None otherwise.
-
- Raises:
- IndexError: The specified column does not exist.
- """
- for row in self._table[1:]:
- if row[column] == value:
- return row
- return None
-
- def AddColumn(self, column, default='', col_index=-1):
- """Appends a new column to the table.
-
- Args:
- column: A string, name of the column to add.
- default: Default value for entries. Defaults to ''.
- col_index: Integer index for where to insert new column.
-
- Raises:
- TableError: Column name already exists.
-
- """
- if column in self.table:
- raise TableError('Column %r already in table.' % column)
- if col_index == -1:
- self._table[0][column] = column
- for i in range(1, len(self._table)):
- self._table[i][column] = default
- else:
- self._table[0].Insert(column, column, col_index)
- for i in range(1, len(self._table)):
- self._table[i].Insert(column, default, col_index)
-
- def Append(self, new_values):
- """Adds a new row (list) to the table.
-
- Args:
- new_values: Tuple, dict, or Row() of new values to append as a row.
-
- Raises:
- TableError: Supplied tuple not equal to table width.
- """
- newrow = self.NewRow()
- newrow.values = new_values
- self._table.append(newrow)
-
- def NewRow(self, value=''):
- """Fetches a new, empty row, with headers populated.
-
- Args:
- value: Initial value to set each row entry to.
-
- Returns:
- A Row() object.
- """
- newrow = self.row_class()
- newrow.row = self.size + 1
- newrow.table = self
- headers = self._Header()
- for header in headers:
- newrow[header] = value
- return newrow
-
- def CsvToTable(self, buf, header=True, separator=','):
- """Parses buffer into tabular format.
-
- Strips off comments (preceded by '#').
- Optionally parses and indexes by first line (header).
-
- Args:
- buf: String file buffer containing CSV data.
- header: Is the first line of buffer a header.
- separator: String that CSV is separated by.
-
- Returns:
- int, the size of the table created.
-
- Raises:
- TableError: A parsing error occurred.
- """
- self.Reset()
-
- header_row = self.row_class()
- if header:
- line = buf.readline()
- header_str = ''
- while not header_str:
- # Remove comments.
- header_str = line.split('#')[0].strip()
- if not header_str:
- line = buf.readline()
-
- header_list = header_str.split(separator)
- header_length = len(header_list)
-
- for entry in header_list:
- entry = entry.strip()
- if entry in header_row:
- raise TableError('Duplicate header entry %r.' % entry)
-
- header_row[entry] = entry
- header_row.row = 0
- self._table[0] = header_row
-
- # xreadlines would be better but not supported by StringIO for testing.
- for line in buf:
- # Support commented lines, provide '#' is first character of line.
- if line.startswith('#'):
- continue
-
- lst = line.split(separator)
- lst = [l.strip() for l in lst]
- if header and len(lst) != header_length:
- # Silently drop illegal line entries
- continue
- if not header:
- header_row = self.row_class()
- header_length = len(lst)
- header_row.values = dict(zip(range(header_length),
- range(header_length)))
- self._table[0] = header_row
- header = True
- continue
-
- new_row = self.NewRow()
- new_row.values = lst
- header_row.row = self.size + 1
- self._table.append(new_row)
-
- return self.size
-
- def index(self, name=None): # pylint: disable=C6409
- """Returns index number of supplied column name.
-
- Args:
- name: string of column name.
-
- Raises:
- TableError: If name not found.
-
- Returns:
- Index of the specified header entry.
- """
- try:
- return self.header.index(name)
- except ValueError:
- raise TableError('Unknown index name %s.' % name)
diff --git a/netmiko/a10/__init__.py b/netmiko/a10/__init__.py
index c1ebaf4ea..6d812d3ca 100644
--- a/netmiko/a10/__init__.py
+++ b/netmiko/a10/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.a10.a10_ssh import A10SSH
-__all__ = ['A10SSH']
+__all__ = ["A10SSH"]
diff --git a/netmiko/a10/a10_ssh.py b/netmiko/a10/a10_ssh.py
index dd9e752a0..5ca269d7a 100644
--- a/netmiko/a10/a10_ssh.py
+++ b/netmiko/a10/a10_ssh.py
@@ -1,25 +1,22 @@
"""A10 support."""
-from __future__ import unicode_literals
-import time
from netmiko.cisco_base_connection import CiscoSSHConnection
class A10SSH(CiscoSSHConnection):
"""A10 support."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""A10 requires to be enable mode to disable paging."""
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
self.enable()
- self.disable_paging(command="terminal length 0")
- # Will not do anything without A10 specific command
- self.set_terminal_width()
-
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ # terminal width ill not do anything without A10 specific command
+ # self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/accedian/__init__.py b/netmiko/accedian/__init__.py
index 785595327..d2c2800f5 100644
--- a/netmiko/accedian/__init__.py
+++ b/netmiko/accedian/__init__.py
@@ -1,3 +1,3 @@
from netmiko.accedian.accedian_ssh import AccedianSSH
-__all__ = ['AccedianSSH']
+__all__ = ["AccedianSSH"]
diff --git a/netmiko/accedian/accedian_ssh.py b/netmiko/accedian/accedian_ssh.py
index 1ffabfa42..3167c74fb 100644
--- a/netmiko/accedian/accedian_ssh.py
+++ b/netmiko/accedian/accedian_ssh.py
@@ -1,45 +1,32 @@
-from __future__ import unicode_literals
-import time
+from typing import Optional
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
from netmiko.cisco_base_connection import CiscoSSHConnection
-class AccedianSSH(CiscoSSHConnection):
- def session_preparation(self):
- self._test_channel_read()
+class AccedianSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[:#]")
self.set_base_prompt()
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def check_enable_mode(self, *args, **kwargs):
- raise AttributeError("Accedian devices do not support enable mode!")
-
- def enable(self, *args, **kwargs):
- raise AttributeError("Accedian devices do not support enable mode!")
-
- def exit_enable_mode(self, *args, **kwargs):
- raise AttributeError("Accedian devices do not support enable mode!")
-
- def check_config_mode(self):
- """Accedian devices do not have a config mode."""
- return False
-
- def config_mode(self):
- """Accedian devices do not have a config mode."""
- return ''
-
- def exit_config_mode(self):
- """Accedian devices do not have a config mode."""
- return ''
-
- def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='#',
- delay_factor=2):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
- super(AccedianSSH, self).set_base_prompt(pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
return self.base_prompt
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/adtran/__init__.py b/netmiko/adtran/__init__.py
new file mode 100644
index 000000000..354eae20a
--- /dev/null
+++ b/netmiko/adtran/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.adtran.adtran import AdtranOSSSH, AdtranOSTelnet
+
+__all__ = ["AdtranOSSSH", "AdtranOSTelnet"]
diff --git a/netmiko/adtran/adtran.py b/netmiko/adtran/adtran.py
new file mode 100644
index 000000000..225edb87e
--- /dev/null
+++ b/netmiko/adtran/adtran.py
@@ -0,0 +1,73 @@
+from typing import Any, Optional
+import re
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class AdtranOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config term", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+class AdtranOSSSH(AdtranOSBase):
+ pass
+
+
+class AdtranOSTelnet(AdtranOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/alcatel/__init__.py b/netmiko/alcatel/__init__.py
index f3d15dd2f..fe6f2d35d 100644
--- a/netmiko/alcatel/__init__.py
+++ b/netmiko/alcatel/__init__.py
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-from netmiko.alcatel.alcatel_sros_ssh import AlcatelSrosSSH
from netmiko.alcatel.alcatel_aos_ssh import AlcatelAosSSH
-__all__ = ['AlcatelSrosSSH', 'AlcatelAosSSH']
+__all__ = ["AlcatelAosSSH"]
diff --git a/netmiko/alcatel/alcatel_aos_ssh.py b/netmiko/alcatel/alcatel_aos_ssh.py
index 9c2c58c1f..6c8da7a8d 100644
--- a/netmiko/alcatel/alcatel_aos_ssh.py
+++ b/netmiko/alcatel/alcatel_aos_ssh.py
@@ -1,44 +1,24 @@
"""Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
from netmiko.cisco_base_connection import CiscoSSHConnection
-class AlcatelAosSSH(CiscoSSHConnection):
+class AlcatelAosSSH(NoEnable, NoConfig, CiscoSSHConnection):
"""Alcatel-Lucent Enterprise AOS support (AOS6 and AOS8)."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
# Prompt can be anything, but best practice is to end with > or #
- self._test_channel_read(pattern=r'[>#]')
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def check_enable_mode(self, *args, **kwargs):
- """No enable mode on AOS"""
- pass
-
- def enable(self, *args, **kwargs):
- """No enable mode on AOS"""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on AOS"""
- pass
-
- def check_config_mode(self, *args, **kwargs):
- """No config mode on AOS"""
- pass
-
- def config_mode(self, *args, **kwargs):
- """No config mode on AOS"""
- return ''
-
- def exit_config_mode(self, *args, **kwargs):
- """No config mode on AOS"""
- return ''
- def save_config(self, cmd='write memory flash-synchro', confirm=False):
+ def save_config(
+ self,
+ cmd: str = "write memory flash-synchro",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Save Config"""
- return super(AlcatelAosSSH, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/alcatel/alcatel_sros_ssh.py b/netmiko/alcatel/alcatel_sros_ssh.py
deleted file mode 100644
index 21ec9cf0b..000000000
--- a/netmiko/alcatel/alcatel_sros_ssh.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""Alcatel-Lucent SROS support."""
-from __future__ import print_function
-from __future__ import unicode_literals
-import re
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class AlcatelSrosSSH(CiscoSSHConnection):
- """Alcatel-Lucent SROS support."""
- def session_preparation(self):
- self._test_channel_read()
- self.set_base_prompt()
- self.disable_paging(command="environment no more")
- # Clear the read buffer
- time.sleep(.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(AlcatelSrosSSH, self).set_base_prompt(*args, **kwargs)
- match = re.search(r'(.*)(>.*)*#', cur_base_prompt)
- if match:
- # strip off >... from base_prompt
- self.base_prompt = match.group(1)
- return self.base_prompt
-
- def enable(self, *args, **kwargs):
- pass
-
- def config_mode(self, config_command='configure', pattern='#'):
- """ Enter into configuration mode on SROS device."""
- return super(AlcatelSrosSSH, self).config_mode(config_command=config_command,
- pattern=pattern)
-
- def exit_config_mode(self, exit_config='exit all', pattern='#'):
- """ Exit from configuration mode."""
- return super(AlcatelSrosSSH, self).exit_config_mode(exit_config=exit_config,
- pattern=pattern)
-
- def check_config_mode(self, check_string='config', pattern='#'):
- """ Checks if the device is in configuration mode or not. """
- return super(AlcatelSrosSSH, self).check_config_mode(check_string=check_string,
- pattern=pattern)
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
- """Not Implemented"""
- raise NotImplementedError
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..33af638b3
--- /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) -> None:
+ """
+ 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) -> str:
+ """Enter the Bourne Shell."""
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
+
+ def _return_cli(self) -> str:
+ """Return to the Awplus CLI."""
+ return self._send_command_str("exit", expect_string=r"[#>]")
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "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/apresia/__init__.py b/netmiko/apresia/__init__.py
new file mode 100644
index 000000000..3992c66d1
--- /dev/null
+++ b/netmiko/apresia/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.apresia.apresia_aeos import ApresiaAeosSSH, ApresiaAeosTelnet
+
+__all__ = ["ApresiaAeosSSH", "ApresiaAeosTelnet"]
diff --git a/netmiko/apresia/apresia_aeos.py b/netmiko/apresia/apresia_aeos.py
new file mode 100644
index 000000000..8ef0f5ea3
--- /dev/null
+++ b/netmiko/apresia/apresia_aeos.py
@@ -0,0 +1,44 @@
+from typing import Any, Optional
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ApresiaAeosBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+
+ self.enable()
+ check_command = f"show running-config | include {command}"
+ show_run = self._send_command_str(check_command)
+
+ output = ""
+ if self.allow_auto_change and command not in show_run:
+ output += super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+ self.exit_enable_mode()
+ return output
+
+
+class ApresiaAeosSSH(ApresiaAeosBase):
+ pass
+
+
+class ApresiaAeosTelnet(ApresiaAeosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/arista/__init__.py b/netmiko/arista/__init__.py
index 274f1acb2..3b0def0ff 100644
--- a/netmiko/arista/__init__.py
+++ b/netmiko/arista/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.arista.arista import AristaSSH, AristaTelnet, AristaFileTransfer
-__all__ = ['AristaSSH', 'AristaTelnet', 'AristaFileTransfer']
+__all__ = ["AristaSSH", "AristaTelnet", "AristaFileTransfer"]
diff --git a/netmiko/arista/arista.py b/netmiko/arista/arista.py
index d5f7218f1..ece8859ed 100644
--- a/netmiko/arista/arista.py
+++ b/netmiko/arista/arista.py
@@ -1,22 +1,36 @@
-from __future__ import unicode_literals
-import time
+from typing import Any, Optional, Union, Sequence
+from typing import TYPE_CHECKING
+import re
from netmiko.cisco_base_connection import CiscoSSHConnection
from netmiko.cisco_base_connection import CiscoFileTransfer
-from netmiko import log
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
class AristaBase(CiscoSSHConnection):
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r'[>#]')
+ cmd = "terminal width 511"
+ # Arista will echo immediately and then when the device really responds (like NX-OS)
+ self.set_terminal_width(command=cmd, pattern=r"Width set to")
+ self.disable_paging(cmd_verify=False, pattern=r"Pagination disabled")
self.set_base_prompt()
- self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def check_config_mode(self, check_string=')#', pattern=''):
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
"""
Checks if the device is in configuration mode or not.
@@ -25,22 +39,40 @@ def check_config_mode(self, check_string=')#', pattern=''):
Can also be (s2)
"""
- log.debug("pattern: {0}".format(pattern))
self.write_channel(self.RETURN)
output = self.read_until_pattern(pattern=pattern)
- log.debug("check_config_mode: {0}".format(repr(output)))
output = output.replace("(s1)", "")
output = output.replace("(s2)", "")
- log.debug("check_config_mode: {0}".format(repr(output)))
return check_string in output
- def _enter_shell(self):
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Force arista to read pattern all the way to prompt on the next line."""
+
+ if not re_flags:
+ re_flags = re.DOTALL
+ check_string = re.escape(")#")
+
+ if not pattern:
+ pattern = re.escape(self.base_prompt[:16])
+ pattern = f"{pattern}.*{check_string}"
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
"""Enter the Bourne Shell."""
- return self.send_command('bash', expect_string=r"[\$#]")
+ output = self._send_command_str("bash", expect_string=r"[\$#]")
+ return output
- def _return_cli(self):
+ def _return_cli(self) -> str:
"""Return to the CLI."""
- return self.send_command('exit', expect_string=r"[#>]")
+ output = self._send_command_str("exit", expect_string=r"[#>]")
+ return output
class AristaSSH(AristaBase):
@@ -48,46 +80,64 @@ class AristaSSH(AristaBase):
class AristaTelnet(AristaBase):
- 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(AristaTelnet, self).__init__(*args, **kwargs)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
class AristaFileTransfer(CiscoFileTransfer):
"""Arista SCP File Transfer driver."""
- def __init__(self, ssh_conn, source_file, dest_file, file_system="/mnt/flash", direction='put'):
- return super(AristaFileTransfer, self).__init__(ssh_conn=ssh_conn,
- source_file=source_file,
- dest_file=dest_file,
- file_system=file_system,
- direction=direction)
-
- def remote_space_available(self, search_pattern=""):
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/mnt/flash",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
"""Return space available on remote device."""
return self._remote_space_available_unix(search_pattern=search_pattern)
- def check_file_exists(self, remote_cmd=""):
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
return self._check_file_exists_unix(remote_cmd=remote_cmd)
- def remote_file_size(self, remote_cmd="", remote_file=None):
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""Get the file size of the remote file."""
- return self._remote_file_size_unix(remote_cmd=remote_cmd, remote_file=remote_file)
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
- def remote_md5(self, base_cmd='verify /md5', remote_file=None):
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
if remote_file is None:
- if self.direction == 'put':
+ if self.direction == "put":
remote_file = self.dest_file
- elif self.direction == 'get':
+ elif self.direction == "get":
remote_file = self.source_file
- remote_md5_cmd = "{} file:{}/{}".format(base_cmd, self.file_system, remote_file)
- dest_md5 = self.ssh_ctl_chan.send_command(remote_md5_cmd, max_loops=750, delay_factor=4)
+ remote_md5_cmd = f"{base_cmd} file:{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=600)
dest_md5 = self.process_md5(dest_md5)
return dest_md5
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: Union[str, Sequence[str], None] = None) -> None:
raise NotImplementedError
diff --git a/netmiko/arista/arista_ssh.py b/netmiko/arista/arista_ssh.py
deleted file mode 100644
index 5de156be4..000000000
--- a/netmiko/arista/arista_ssh.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoSSHConnection
-from netmiko import log
-
-
-class AristaSSH(CiscoSSHConnection):
- def session_preparation(self):
- """Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r'[>#]')
- self.set_base_prompt()
- self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
-
- def check_config_mode(self, check_string=')#', pattern=''):
- """
- Checks if the device is in configuration mode or not.
-
- Arista, unfortunately, does this:
- loc1-core01(s1)#
-
- Can also be (s2)
- """
- log.debug("pattern: {0}".format(pattern))
- self.write_channel('\n')
- output = self.read_until_pattern(pattern=pattern)
- log.debug("check_config_mode: {0}".format(repr(output)))
- output = output.replace("(s1)", "")
- output = output.replace("(s2)", "")
- log.debug("check_config_mode: {0}".format(repr(output)))
- return check_string in output
diff --git a/netmiko/aruba/__init__.py b/netmiko/aruba/__init__.py
index 0a9847d69..e9350eacb 100644
--- a/netmiko/aruba/__init__.py
+++ b/netmiko/aruba/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.aruba.aruba_ssh import ArubaSSH
-__all__ = ['ArubaSSH']
+__all__ = ["ArubaSSH"]
diff --git a/netmiko/aruba/aruba_ssh.py b/netmiko/aruba/aruba_ssh.py
index 98e929b29..c79e8f723 100644
--- a/netmiko/aruba/aruba_ssh.py
+++ b/netmiko/aruba/aruba_ssh.py
@@ -1,31 +1,50 @@
-"""Aruba OS support"""
-from __future__ import unicode_literals
-import time
-import re
+"""
+Aruba OS support.
+
+For use with Aruba OS Controllers.
+
+"""
+from typing import Any
from netmiko.cisco_base_connection import CiscoSSHConnection
class ArubaSSH(CiscoSSHConnection):
"""Aruba OS support"""
- def session_preparation(self):
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ # Aruba has an auto-complete on space behavior that is problematic
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
"""Aruba OS requires enable mode to disable paging."""
- delay_factor = self.select_delay_factor(delay_factor=0)
- time.sleep(1 * delay_factor)
- self._test_channel_read()
+ # Aruba switches output ansi codes
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
self.enable()
- self.disable_paging(command="no paging")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.disable_paging(command="no page")
- def check_config_mode(self, check_string='(config) #', pattern=''):
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = r"[>#]"
+ ) -> bool:
"""
Checks if the device is in configuration mode or not.
Aruba uses "() (config) #" as config prompt
"""
- if not pattern:
- pattern = re.escape(self.base_prompt[:16])
- return super(ArubaSSH, self).check_config_mode(check_string=check_string,
- pattern=pattern)
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure term",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Aruba auto completes on space so 'configure' needs fully spelled-out."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
diff --git a/netmiko/avaya/__init__.py b/netmiko/avaya/__init__.py
deleted file mode 100644
index 54bd407a9..000000000
--- a/netmiko/avaya/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from __future__ import unicode_literals
-from netmiko.avaya.avaya_vsp_ssh import AvayaVspSSH
-from netmiko.avaya.avaya_ers_ssh import AvayaErsSSH
-
-__all__ = ['AvayaVspSSH', 'AvayaErsSSH']
diff --git a/netmiko/avaya/avaya_ers_ssh.py b/netmiko/avaya/avaya_ers_ssh.py
deleted file mode 100644
index f234b78dc..000000000
--- a/netmiko/avaya/avaya_ers_ssh.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""Netmiko support for Avaya Ethernet Routing Switch."""
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-# Avaya presents Enter Ctrl-Y to begin.
-CTRL_Y = '\x19'
-
-
-class AvayaErsSSH(CiscoSSHConnection):
- """Netmiko support for Avaya Ethernet Routing Switch."""
- def special_login_handler(self, delay_factor=1):
- """
- Avaya ERS presents the following as part of the login process:
-
- Enter Ctrl-Y to begin.
- """
- delay_factor = self.select_delay_factor(delay_factor)
-
- # Handle 'Enter Ctrl-Y to begin'
- output = ""
- i = 0
- while i <= 12:
- output = self.read_channel()
- if output:
- if 'Ctrl-Y' in output:
- self.write_channel(CTRL_Y)
- if 'sername' in output:
- self.write_channel(self.username + self.RETURN)
- elif 'ssword' in output:
- self.write_channel(self.password + self.RETURN)
- break
- time.sleep(.5 * delay_factor)
- else:
- self.write_channel(self.RETURN)
- time.sleep(1 * delay_factor)
- i += 1
-
- def save_config(self, cmd='save config', confirm=False):
- """Save Config"""
- return super(AvayaErsSSH, self).save_config(cmd=cmd, confirm=confirm)
diff --git a/netmiko/avaya/avaya_vsp_ssh.py b/netmiko/avaya/avaya_vsp_ssh.py
deleted file mode 100644
index a5cade6c2..000000000
--- a/netmiko/avaya/avaya_vsp_ssh.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"""Avaya Virtual Services Platform Support."""
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class AvayaVspSSH(CiscoSSHConnection):
- """Avaya Virtual Services Platform Support."""
- 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="terminal more disable")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def save_config(self, cmd='save config', confirm=False):
- """Save Config"""
- return super(AvayaVspSSH, self).save_config(cmd=cmd, confirm=confirm)
diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py
index ef557401b..a3a19ded2 100644
--- a/netmiko/base_connection.py
+++ b/netmiko/base_connection.py
@@ -1,165 +1,316 @@
-'''
+"""
Base connection class for netmiko
Handles SSH connection and methods that are generically applicable to different
platforms (Cisco and non-Cisco).
Also defines methods that should generally be supported by child classes
-'''
-
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import paramiko
+"""
+from typing import (
+ Optional,
+ Callable,
+ Any,
+ List,
+ Dict,
+ TypeVar,
+ cast,
+ Type,
+ Sequence,
+ TextIO,
+ Union,
+ Tuple,
+ Deque,
+)
+from typing import TYPE_CHECKING
+from types import TracebackType
+import io
+import re
+import socket
import telnetlib
import time
-import socket
-import re
-import io
-import os
-import logging
+from collections import deque
+from os import path
from threading import Lock
+import functools
+import logging
-from netmiko.netmiko_globals import MAX_BUFFER, BACKSPACE_CHAR
-from netmiko.ssh_exception import NetMikoTimeoutException, NetMikoAuthenticationException, PatternNotFoundException
-from netmiko.utilities import write_bytes, check_serial_port, get_structured_data
-from netmiko.py23_compat import string_types, bytes_io_types
-from netmiko import log
-from datetime import datetime
+import paramiko
import serial
+from tenacity import retry, stop_after_attempt, wait_exponential
+import warnings
+
+from netmiko import log
+from netmiko.netmiko_globals import BACKSPACE_CHAR
+from netmiko.exceptions import (
+ NetmikoTimeoutException,
+ NetmikoAuthenticationException,
+ ConfigInvalidException,
+ ReadException,
+ ReadTimeout,
+)
+from netmiko.channel import Channel, SSHChannel, TelnetChannel, SerialChannel
+from netmiko.session_log import SessionLog
+from netmiko.utilities import (
+ write_bytes,
+ check_serial_port,
+ structured_data_converter,
+ run_ttp_template,
+ select_cmd_verify,
+ calc_old_timeout,
+)
+from netmiko.utilities import m_exec_time # noqa
+
+if TYPE_CHECKING:
+ from os import PathLike
+
+# For decorators
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+DELAY_FACTOR_DEPR_SIMPLE_MSG = """\n
+Netmiko 4.x and later has deprecated the use of delay_factor and/or
+max_loops in this context. You should remove any use of delay_factor=x
+from this method call.\n"""
+
+
+# Logging filter for #2597
+class SecretsFilter(logging.Filter):
+ def __init__(self, no_log: Optional[Dict[Any, str]] = None) -> None:
+ self.no_log = no_log
+
+ def filter(self, record: logging.LogRecord) -> bool:
+ """Removes secrets (no_log) from messages"""
+ if self.no_log:
+ for hidden_data in self.no_log.values():
+ record.msg = record.msg.replace(hidden_data, "********")
+ return True
+
+
+def lock_channel(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ self._lock_netmiko_session()
+ try:
+ return_val = func(self, *args, **kwargs)
+ finally:
+ # Always unlock the channel, even on exception.
+ self._unlock_netmiko_session()
+ return return_val
+ return cast(F, wrapper_decorator)
-#paramiko.util.log_to_file("test_paramiko.log", level = "DEBUG")
-work_dir = os.getenv('CAFYKIT_WORK_DIR')
-print(f"#######work_dir = {work_dir}")
-if work_dir:
- formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S')
- paramiko_log_folder = os.path.join(work_dir, 'test_paramiko.log')
- paramiko.util.log_to_file(paramiko_log_folder, level = "DEBUG")
- fh = logging.FileHandler(paramiko_log_folder)
- fh.setFormatter(formatter)
- log = logging.getLogger("netmiko")
- log.addHandler(fh)
- log.setLevel(logging.DEBUG)
- log.addHandler(fh)
-else:
- from netmiko import log
-#print("All loggers in this process: ------ ", logging.root.manager.loggerDict)
+def log_writes(func: F) -> F:
+ """Handle both session_log and log of writes."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", out_data: str) -> None:
+ func(self, out_data)
+ try:
+ log.debug(
+ "write_channel: {}".format(
+ str(write_bytes(out_data, encoding=self.encoding))
+ )
+ )
+ if self.session_log:
+ if self.session_log.fin or self.session_log.record_writes:
+ self.session_log.write(out_data)
+ except UnicodeDecodeError:
+ # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
+ pass
+ return None
+
+ return cast(F, wrapper_decorator)
-class BaseConnection(object):
+class BaseConnection:
"""
Defines vendor independent methods.
Otherwise method left as a stub method.
"""
- def __init__(self, ip='', host='', username='', password='', secret='', port=None,
- device_type='', verbose=False, global_delay_factor=1, use_keys=False,
- key_file=None, allow_agent=False, ssh_strict=False, system_host_keys=False,
- alt_host_keys=False, alt_key_file='', ssh_config_file=None, timeout=90,
- session_timeout=60, blocking_timeout=8, keepalive=0, default_enter=None,
- response_return=None, serial_settings=None, fast_cli=False, session_log=None):
+
+ def __init__(
+ self,
+ ip: str = "",
+ host: str = "",
+ username: str = "",
+ password: Optional[str] = None,
+ secret: str = "",
+ port: Optional[int] = None,
+ device_type: str = "",
+ verbose: bool = False,
+ global_delay_factor: float = 1.0,
+ global_cmd_verify: Optional[bool] = None,
+ use_keys: bool = False,
+ key_file: Optional[str] = None,
+ pkey: Optional[paramiko.PKey] = None,
+ passphrase: Optional[str] = None,
+ disabled_algorithms: Optional[Dict[str, Any]] = None,
+ allow_agent: bool = False,
+ ssh_strict: bool = False,
+ system_host_keys: bool = False,
+ alt_host_keys: bool = False,
+ alt_key_file: str = "",
+ ssh_config_file: Optional[str] = None,
+ #
+ # Connect timeouts
+ # ssh-connect --> TCP conn (conn_timeout) --> SSH-banner (banner_timeout)
+ # --> Auth response (auth_timeout)
+ conn_timeout: int = 10,
+ # Timeout to wait for authentication response
+ auth_timeout: Optional[int] = None,
+ banner_timeout: int = 15, # Timeout to wait for the banner to be presented
+ # Other timeouts
+ blocking_timeout: int = 20, # Read blocking timeout
+ timeout: int = 100, # TCP connect timeout | overloaded to read-loop timeout
+ session_timeout: int = 60, # Used for locking/sharing the connection
+ read_timeout_override: Optional[float] = None,
+ keepalive: int = 0,
+ default_enter: Optional[str] = None,
+ response_return: Optional[str] = None,
+ serial_settings: Optional[Dict[str, Any]] = None,
+ fast_cli: bool = True,
+ _legacy_mode: bool = False,
+ session_log: Optional[SessionLog] = None,
+ session_log_record_writes: bool = False,
+ session_log_file_mode: str = "write",
+ allow_auto_change: bool = False,
+ encoding: str = "ascii",
+ sock: Optional[socket.socket] = None,
+ auto_connect: bool = True,
+ delay_factor_compat: bool = False,
+ ) -> None:
"""
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 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: Path to a file to write the session to.
- :type session_log: str
+
: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.
+
+ :param passphrase: Passphrase to use for encrypted key; password will be used for key
+ decryption if not specified.
+
+ :param disabled_algorithms: Dictionary of SSH algorithms to disable. Refer to the Paramiko
+ documentation for a description of the expected format.
: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 user's 'known_hosts' file.
- :type system_host_keys: bool
+ :param system_host_keys: Load host keys from the users known_hosts file.
+
:param alt_host_keys: If `True` host keys will be loaded from the file specified in
- 'alt_key_file'.
- :type alt_host_keys: bool
+ alt_key_file.
: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.
+
+ :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
: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: '\n').
- :type default_enter: str
+ :param default_enter: Character(s) to send to correspond to enter key (default: \n).
:param response_return: Character(s) to use in normalized return data to represent
- enter key (default: '\n')
- :type response_return: str
+ enter key (default: \n)
+
+ :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: True)
+
+ :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+
+ :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).
+
+ :param session_log_file_mode: "write" or "append" for session_log file mode
+ (default: "write")
+
+ :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+ (default: False)
+
+ :param encoding: Encoding to be used when writing bytes to the output channel.
+ (default: ascii)
+
+ :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+ communication to the target host (default: None).
+
+ :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.
+
+ :param auto_connect: Control whether Netmiko automatically establishes the connection as
+ part of the object creation (default: True).
+
+ :param delay_factor_compat: Set send_command and send_command_timing back to using Netmiko
+ 3.x behavior for delay_factor/global_delay_factor/max_loops. This argument will be
+ eliminated in Netmiko 5.x (default: False).
"""
- self.remote_conn = None
- self.RETURN = '\n' if default_enter is None else default_enter
- self.TELNET_RETURN = '\r\n'
+
+ self.remote_conn: Union[
+ None, telnetlib.Telnet, paramiko.Channel, serial.Serial
+ ] = None
+ # Does the platform support a configuration mode
+ self._config_mode = True
+ self._read_buffer = ""
+ self.delay_factor_compat = delay_factor_compat
+
+ self.TELNET_RETURN = "\r\n"
+ if default_enter is None:
+ if "telnet" not in device_type:
+ self.RETURN = "\n"
+ else:
+ self.RETURN = self.TELNET_RETURN
+ else:
+ self.RETURN = default_enter
+
# Line Separator in response lines
- self.RESPONSE_RETURN = '\n' if response_return is None else response_return
+ self.RESPONSE_RETURN = "\n" if response_return is None else response_return
if ip:
- self.host = ip
- self.ip = ip
+ self.host = ip.strip()
elif host:
- self.host = host
- if not ip and not host and 'serial' not in device_type:
+ self.host = host.strip()
+ if not ip and not host and "serial" not in device_type:
raise ValueError("Either ip or host must be set")
if port is None:
- if 'telnet' in device_type:
+ if "telnet" in device_type:
port = 23
else:
port = 22
@@ -171,63 +322,92 @@ def __init__(self, ip='', host='', username='', password='', secret='', port=Non
self.device_type = device_type
self.ansi_escape_codes = False
self.verbose = verbose
- self.timeout = timeout
- self.session_timeout = session_timeout
+ self.auth_timeout = auth_timeout
+ self.banner_timeout = banner_timeout
self.blocking_timeout = blocking_timeout
+ self.conn_timeout = conn_timeout
+ self.session_timeout = session_timeout
+ self.timeout = timeout
+ self.read_timeout_override = read_timeout_override
self.keepalive = keepalive
- self._session_log = None
+ self.allow_auto_change = allow_auto_change
+ self.encoding = encoding
+ self.sock = sock
+ self.fast_cli = fast_cli
+ self._legacy_mode = _legacy_mode
+ self.global_delay_factor = global_delay_factor
+ self.global_cmd_verify = global_cmd_verify
+ if self.fast_cli and self.global_delay_factor == 1:
+ self.global_delay_factor = 0.1
+ self.session_log = None
+ self._session_log_close = False
+
+ # prevent logging secret data
+ no_log = {}
+ if self.password:
+ no_log["password"] = self.password
+ if self.secret:
+ no_log["secret"] = self.secret
+ log.addFilter(SecretsFilter(no_log=no_log))
+
+ # Netmiko will close the session_log if we open the file
if session_log is not None:
if isinstance(session_log, str):
- self._session_log = open(session_log, mode="ab")
- self._external_session_log = False
- elif isinstance(session_log, bytes_io_types):
- self._session_log = session_log
- self._external_session_log = True
+ # If session_log is a string, open a file corresponding to string name.
+ self.session_log = SessionLog(
+ file_name=session_log,
+ file_mode=session_log_file_mode,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
+ self.session_log.open()
+ elif isinstance(session_log, io.BufferedIOBase):
+ # In-memory buffer or an already open file handle
+ self.session_log = SessionLog(
+ buffered_io=session_log,
+ no_log=no_log,
+ record_writes=session_log_record_writes,
+ )
else:
- raise ValueError("session_log must be a path to a file, "
- "a file handle, or a BufferedIOBase subclass")
+ raise ValueError(
+ "session_log must be a path to a file, a file handle, "
+ "or a BufferedIOBase subclass."
+ )
+
# Default values
self.serial_settings = {
- 'port': 'COM1',
- 'baudrate': 9600,
- 'bytesize': serial.EIGHTBITS,
- 'parity': serial.PARITY_NONE,
- 'stopbits': serial.STOPBITS_ONE
+ "port": "COM1",
+ "baudrate": 9600,
+ "bytesize": serial.EIGHTBITS,
+ "parity": serial.PARITY_NONE,
+ "stopbits": serial.STOPBITS_ONE,
}
if serial_settings is None:
serial_settings = {}
self.serial_settings.update(serial_settings)
- if 'serial' in device_type:
- self.host = 'serial'
- comm_port = self.serial_settings.pop('port')
+ if "serial" in device_type:
+ self.host = "serial"
+ comm_port = self.serial_settings.pop("port")
# Get the proper comm port reference if a name was enterred
comm_port = check_serial_port(comm_port)
- self.serial_settings.update({'port': comm_port})
+ self.serial_settings.update({"port": comm_port})
- self.fast_cli = fast_cli
- self.global_delay_factor = global_delay_factor
- if self.fast_cli and self.global_delay_factor == 1:
- self.global_delay_factor = .1
-
# set in set_base_prompt method
- self.base_prompt = ''
+ self.base_prompt = ""
self._session_locker = Lock()
# determine if telnet or SSH
- if '_telnet' in device_type:
- self.protocol = 'telnet'
- self._modify_connection_params()
- self.establish_connection()
- self.session_preparation()
- elif '_serial' in device_type:
- self.protocol = 'serial'
- self._modify_connection_params()
- self.establish_connection()
- self.session_preparation()
+ if "_telnet" in device_type:
+ self.protocol = "telnet"
+ self.password = password or ""
+ elif "_serial" in device_type:
+ self.protocol = "serial"
+ self.password = password or ""
else:
- self.protocol = 'ssh'
+ self.protocol = "ssh"
+ self.key_policy: paramiko.client.MissingHostKeyPolicy
if not ssh_strict:
self.key_policy = paramiko.AutoAddPolicy()
else:
@@ -235,33 +415,49 @@ def __init__(self, ip='', host='', username='', password='', secret='', port=Non
# Options for SSH host_keys
self.use_keys = use_keys
- self.key_file = key_file
+ self.key_file = (
+ path.abspath(path.expanduser(key_file)) if key_file else None
+ )
+ self.pkey = pkey
+ self.passphrase = passphrase
self.allow_agent = allow_agent
self.system_host_keys = system_host_keys
self.alt_host_keys = alt_host_keys
self.alt_key_file = alt_key_file
+ self.disabled_algorithms = disabled_algorithms or {}
# For SSH proxy support
self.ssh_config_file = ssh_config_file
- self._modify_connection_params()
- self.establish_connection()
- self.session_preparation()
+ # Establish the remote connection
+ if auto_connect:
+ self._open()
+
+ def _open(self) -> None:
+ """Decouple connection creation from __init__ for mocking."""
+ self._modify_connection_params()
+ self.establish_connection()
+ self._try_session_preparation()
- def __enter__(self):
+ def __enter__(self) -> "BaseConnection":
"""Establish a session using a Context Manager."""
return self
- def __exit__(self, exc_type, exc_value, traceback):
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
"""Gracefully close connection on Context Manager exit."""
self.disconnect()
- def _modify_connection_params(self):
+ def _modify_connection_params(self) -> None:
"""Modify connection parameters prior to SSH connection."""
pass
- def _timeout_exceeded(self, start, msg='Timeout exceeded!'):
- """Raise NetMikoTimeoutException if waiting too much in the serving queue.
+ def _timeout_exceeded(self, start: float, msg: str = "Timeout exceeded!") -> bool:
+ """Raise NetmikoTimeoutException if waiting too much in the serving queue.
:param start: Initial start time to see if session lock timeout has been exceeded
:type start: float (from time.time() call i.e. epoch time)
@@ -274,10 +470,10 @@ def _timeout_exceeded(self, start, msg='Timeout exceeded!'):
return False
if time.time() - start > self.session_timeout:
# session_timeout exceeded
- raise NetMikoTimeoutException(msg)
+ raise NetmikoTimeoutException(msg)
return False
- def _lock_netmiko_session(self, start=None):
+ def _lock_netmiko_session(self, start: Optional[float] = None) -> bool:
"""Try to acquire the Netmiko session lock. If not available, wait in the queue until
the channel is available again.
@@ -287,71 +483,56 @@ def _lock_netmiko_session(self, start=None):
if not start:
start = time.time()
# Wait here until the SSH channel lock is acquired or until session_timeout exceeded
- while (not self._session_locker.acquire(False) and
- not self._timeout_exceeded(start, 'The netmiko channel is not available!')):
- time.sleep(.1)
+ while not self._session_locker.acquire(False) and not self._timeout_exceeded(
+ start, "The netmiko channel is not available!"
+ ):
+ time.sleep(0.1)
return True
- def _unlock_netmiko_session(self):
+ def _unlock_netmiko_session(self) -> None:
"""
Release the channel at the end of the task.
"""
if self._session_locker.locked():
self._session_locker.release()
- def _write_channel(self, out_data):
- """Generic handler that will write to both SSH and telnet channel.
+ def _autodetect_fs(self, cmd: str = "", pattern: str = "") -> str:
+ raise NotImplementedError
- :param out_data: data to be written to the channel
- :type out_data: str (can be either unicode/byte string)
- """
- if self.protocol == 'ssh':
- self.remote_conn.sendall(write_bytes(out_data))
- elif self.protocol == 'telnet':
- self.remote_conn.write(write_bytes(out_data))
- elif self.protocol == 'serial':
- self.remote_conn.write(write_bytes(out_data))
- self.remote_conn.flush()
- else:
- raise ValueError("Invalid protocol specified")
- try:
- log.debug("write_channel: {}".format(write_bytes(out_data)))
- self._write_session_log(out_data)
- except UnicodeDecodeError:
- # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
- pass
+ def _enter_shell(self) -> str:
+ raise NotImplementedError
+
+ def _return_cli(self) -> str:
+ raise NotImplementedError
- def _write_session_log(self, data):
- if self._session_log is not None and len(data) > 0:
- self._session_log.write(write_bytes(data))
- self._session_log.flush()
-
- def write_channel(self, out_data):
- """Generic handler that will write to both SSH and telnet channel.
+ @lock_channel
+ @log_writes
+ def write_channel(self, out_data: str) -> None:
+ """Generic method that will write data out the channel.
:param out_data: data to be written to the channel
- :type out_data: str (can be either unicode/byte string)
+ :type out_data: str
"""
- self._lock_netmiko_session()
- try:
- self._write_channel(out_data)
- finally:
- # Always unlock the SSH channel, even on exception.
- self._unlock_netmiko_session()
+ self.channel.write_channel(out_data)
- def is_alive(self):
+ def is_alive(self) -> bool:
"""Returns a boolean flag with the state of the connection."""
null = chr(0)
if self.remote_conn is None:
log.error("Connection is not initialised, is_alive returns False")
return False
- if self.protocol == 'telnet':
+ if self.protocol == "telnet":
try:
- # Try sending IAC + NOP (IAC is telnet way of sending command
- # IAC = Interpret as Command (it comes before the NOP)
+ # Try sending IAC + NOP (IAC is telnet way of sending command)
+ # IAC = Interpret as Command; it comes before the NOP.
log.debug("Sending IAC + NOP")
- self.write_channel(telnetlib.IAC + telnetlib.NOP)
- return True
+ # Need to send multiple times to test connection
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
+ telnet_socket = self.remote_conn.get_socket()
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ telnet_socket.sendall(telnetlib.IAC + telnetlib.NOP)
+ return True
except AttributeError:
return False
else:
@@ -360,210 +541,276 @@ def is_alive(self):
# Try sending ASCII null byte to maintain the connection alive
log.debug("Sending the NULL byte")
self.write_channel(null)
- return self.remote_conn.transport.is_active()
+ assert isinstance(self.remote_conn, paramiko.Channel)
+ assert self.remote_conn.transport is not None
+ result = self.remote_conn.transport.is_active()
+ assert isinstance(result, bool)
+ return result
except (socket.error, EOFError):
log.error("Unable to send", exc_info=True)
# If unable to send, we can tell for sure that the connection is unusable
return False
return False
- def _read_channel(self):
- """Generic handler that will read all the data from an SSH or telnet channel."""
- if self.protocol == 'ssh':
- output = ""
- while True:
- if self.remote_conn.recv_ready():
- outbuf = self.remote_conn.recv(MAX_BUFFER)
- if len(outbuf) == 0:
- raise EOFError("Channel stream closed by remote device.")
- output += outbuf.decode('utf-8', 'ignore')
- else:
- break
- elif self.protocol == 'telnet':
- output = self.remote_conn.read_very_eager().decode('utf-8', 'ignore')
- elif self.protocol == 'serial':
- output = ""
- while (self.remote_conn.in_waiting > 0):
- output += self.remote_conn.read(self.remote_conn.in_waiting)
- log.debug("read_channel: {}".format(output))
- self._write_session_log(output)
- return output
-
- def read_channel(self):
- """Generic handler that will read all the data from an SSH or telnet channel."""
- output = ""
- self._lock_netmiko_session()
- try:
- output = self._read_channel()
- finally:
- # Always unlock the SSH channel, even on exception.
- self._unlock_netmiko_session()
+ @lock_channel
+ def read_channel(self) -> str:
+ """Generic handler that will read all the data from given channel."""
+ new_data = self.channel.read_channel()
+ new_data = self.normalize_linefeeds(new_data)
+ if self.ansi_escape_codes:
+ new_data = self.strip_ansi_escape_codes(new_data)
+ log.debug(f"read_channel: {new_data}")
+ if self.session_log:
+ self.session_log.write(new_data)
+
+ # If data had been previously saved to the buffer, the prepend it to output
+ # do post read_channel so session_log/log doesn't record buffered data twice
+ if self._read_buffer:
+ output = self._read_buffer + new_data
+ self._read_buffer = ""
+ else:
+ output = new_data
return output
- def _read_channel_expect(self, pattern='', re_flags=0, max_loops=150):
- """Function that reads channel until pattern is detected.
-
- pattern takes a regular expression.
+ def read_until_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel until pattern is detected.
- By default pattern will be self.base_prompt
+ Will return string up to and including pattern.
- Note: this currently reads beyond pattern. In the case of SSH it reads MAX_BUFFER.
- In the case of telnet it reads all non-blocking data.
+ Returns ReadTimeout if pattern not detected in read_timeout seconds.
- There are dependencies here like determining whether in config_mode that are actually
- depending on reading beyond pattern.
+ :param pattern: Regular expression pattern used to identify that reading is done.
- :param pattern: Regular expression pattern used to identify the command is done \
- (defaults to self.base_prompt)
- :type pattern: str (regular expression)
+ :param read_timeout: maximum time to wait looking for pattern. Will raise ReadTimeout.
+ A read_timeout value of 0 will cause the loop to never timeout (i.e. it will keep
+ reading indefinitely until pattern is detected.
- :param re_flags: regex flags used in conjunction with pattern to search for prompt \
- (defaults to no flags)
- :type re_flags: int
+ :param re_flags: regex flags used in conjunction with pattern (defaults to no flags).
- :param max_loops: max number of iterations to read the channel before raising exception.
- Will default to be based upon self.timeout.
- :type max_loops: int
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
"""
- output = ''
- if not pattern:
- pattern = re.escape(self.base_prompt)
- log.debug("Pattern is: {}".format(pattern))
+ if max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of max_loops with read_until_pattern.
+You should convert all uses of max_loops over to read_timeout=x
+where x is the total number of seconds to wait before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
- i = 1
- loop_delay = .1
- # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
- # argument for backwards compatibility).
- if max_loops == 150:
- max_loops = self.timeout / loop_delay
- while i < max_loops:
- if self.protocol == 'ssh':
- try:
- # If no data available will wait timeout seconds trying to read
- self._lock_netmiko_session()
- new_data = self.remote_conn.recv(MAX_BUFFER)
- if len(new_data) == 0:
- raise EOFError("Channel stream closed by remote device.")
- new_data = new_data.decode('utf-8', 'ignore')
- log.debug("_read_channel_expect read_data: {}".format(new_data))
- output += new_data
- self._write_session_log(new_data)
- except socket.timeout:
- raise NetMikoTimeoutException("Timed-out reading channel, data not available.")
- finally:
- self._unlock_netmiko_session()
- elif self.protocol == 'telnet' or 'serial':
- output += self.read_channel()
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ output = ""
+ loop_delay = 0.01
+ start_time = time.time()
+ # if read_timeout == 0 or 0.0 keep reading indefinitely
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ output += self.read_channel()
if re.search(pattern, output, flags=re_flags):
- log.debug("Pattern found: {} {}".format(pattern, output))
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ # The string matched by pattern must be retained in the output string.
+ # re.split will do this if capturing parentesis are used.
+ if len(results) == 2:
+ # no capturing parenthesis, convert and try again.
+ pattern = f"({pattern})"
+ results = re.split(pattern, output, maxsplit=1, flags=re_flags)
+
+ if len(results) != 3:
+ # well, we tried
+ msg = f"""Unable to successfully split output based on pattern:
+pattern={pattern}
+output={repr(output)}
+results={results}
+"""
+ raise ReadException(msg)
+
+ # Process such that everything before and including pattern is return.
+ # Everything else is retained in the _read_buffer
+ output, match_str, buffer = results
+ output = output + match_str
+ if buffer:
+ self._read_buffer += buffer
+ log.debug(f"Pattern found: {pattern} {output}")
return output
- time.sleep(loop_delay * self.global_delay_factor)
- i += 1
- raise NetMikoTimeoutException("Timed-out reading channel, pattern not found in output: {}"
- .format(pattern))
+ time.sleep(loop_delay)
+
+ msg = f"""\n\nPattern not detected: {repr(pattern)} in output.
+
+Things you might try to fix this:
+1. Adjust the regex pattern to better identify the terminating string. Note, in
+many situations the pattern is automatically based on the network device's prompt.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.\n\n"""
+ raise ReadTimeout(msg)
- def _read_channel_timing(self, delay_factor=1, max_loops=150):
+ def read_channel_timing(
+ self,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ ) -> str:
"""Read data on the channel based on timing delays.
- Attempt to read channel max_loops number of times. If no data this will cause a 15 second
- delay.
+ General pattern is keep reading until no new data is read.
+ Once no new data is read wait `last_read` amount of time (one last read).
+ As long as no new data, then return data.
- Once data is encountered read channel for another two seconds (2 * delay_factor) to make
- sure reading of channel is complete.
+ `read_timeout` is an absolute timer for how long to keep reading (which presupposes
+ we are still getting new data).
- :param delay_factor: multiplicative factor to adjust delay when reading channel (delays
- get multiplied by this factor)
- :type delay_factor: int or float
+ Setting `read_timeout` to zero will cause read_channel_timing to never expire based
+ on an absolute timeout. It will only complete based on timeout based on their being
+ no new data.
- :param max_loops: maximum number of loops to iterate through before returning channel data.
- Will default to be based upon self.timeout.
- :type max_loops: int
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
"""
- # Time to delay in each read loop
- loop_delay = .1
- final_delay = 2
- # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
- # and delay_factor arguments for backwards compatibility).
- delay_factor = self.select_delay_factor(delay_factor)
- if delay_factor == 1 and max_loops == 150:
- max_loops = int(self.timeout / loop_delay)
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ # Time to delay in each read loop
+ loop_delay = 0.1
channel_data = ""
- i = 0
- while i <= max_loops:
- time.sleep(loop_delay * delay_factor)
+ start_time = time.time()
+
+ # Set read_timeout to 0 to never timeout
+ while (time.time() - start_time < read_timeout) or (not read_timeout):
+ time.sleep(loop_delay)
new_data = self.read_channel()
+ # gather new output
if new_data:
channel_data += new_data
- else:
- # Safeguard to make sure really done
- time.sleep(final_delay * delay_factor)
+ # if we have some output, but nothing new, then do the last read
+ elif channel_data != "":
+ # Make sure really done (i.e. no new data)
+ time.sleep(last_read)
new_data = self.read_channel()
if not new_data:
break
else:
channel_data += new_data
- i += 1
- return channel_data
-
- def read_until_prompt(self, *args, **kwargs):
- """Read channel until self.base_prompt detected. Return ALL data available."""
- return self._read_channel_expect(*args, **kwargs)
+ else:
+ msg = f"""\n
+read_channel_timing's absolute timer expired.
- def read_until_pattern(self, *args, **kwargs):
- """Read channel until pattern detected. Return ALL data available."""
- return self._read_channel_expect(*args, **kwargs)
+The network device was continually outputting data for longer than {read_timeout}
+seconds.
- def read_until_prompt_or_pattern(self, pattern='', re_flags=0):
- """Read until either self.base_prompt or pattern is detected.
+If this is expected i.e. the command you are executing is continually emitting
+data for a long period of time, then you can set 'read_timeout=x' seconds. If
+you want Netmiko to keep reading indefinitely (i.e. to only stop when there is
+no new data), then you can set 'read_timeout=0'.
- :param pattern: the pattern used to identify that the output is complete (i.e. stop \
- reading when pattern is detected). pattern will be combined with self.base_prompt to \
- terminate output reading when the first of self.base_prompt or pattern is detected.
- :type pattern: regular expression string
+You can look at the Netmiko session_log or debug log for more information.
- :param re_flags: regex flags used in conjunction with pattern to search for prompt \
- (defaults to no flags)
- :type re_flags: int
+"""
+ raise ReadTimeout(msg)
+ return channel_data
- """
- combined_pattern = re.escape(self.base_prompt)
+ def read_until_prompt(
+ self,
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read channel up to and including self.base_prompt."""
+ pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ pattern = f"{pattern}.*"
+ return self.read_until_pattern(
+ pattern=pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def read_until_prompt_or_pattern(
+ self,
+ pattern: str = "",
+ read_timeout: float = 10.0,
+ read_entire_line: bool = False,
+ re_flags: int = 0,
+ max_loops: Optional[int] = None,
+ ) -> str:
+ """Read until either self.base_prompt or pattern is detected."""
+ prompt_pattern = re.escape(self.base_prompt)
+ if read_entire_line:
+ prompt_pattern = f"{prompt_pattern}.*"
if pattern:
- combined_pattern = r"({}|{})".format(combined_pattern, pattern)
- return self._read_channel_expect(combined_pattern, re_flags=re_flags)
-
- def serial_login(self, pri_prompt_terminator=r'#\s*$', alt_prompt_terminator=r'>\s*$',
- username_pattern=r"(?:[Uu]ser:|sername|ogin)", pwd_pattern=r"assword",
- delay_factor=1, max_loops=20):
- self.telnet_login(pri_prompt_terminator, alt_prompt_terminator, username_pattern,
- pwd_pattern, delay_factor, max_loops)
-
- def telnet_login(self, pri_prompt_terminator=r'(?\s*$',
- username_pattern=r"(?:[Uu]ser:|sername|ogin)", pwd_pattern=r"assword",
- delay_factor=1, max_loops=20):
+ combined_pattern = r"(?:{}|{})".format(prompt_pattern, pattern)
+ else:
+ combined_pattern = prompt_pattern
+ return self.read_until_pattern(
+ pattern=combined_pattern,
+ re_flags=re_flags,
+ max_loops=max_loops,
+ read_timeout=read_timeout,
+ )
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:[Uu]ser:|sername|ogin)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
"""Telnet login. Can be username/password or just password.
:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
- :type pri_prompt_terminator: str
:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
- :type alt_prompt_terminator: str
:param username_pattern: Pattern used to identify the username prompt
- :type username_pattern: str
:param delay_factor: See __init__: global_delay_factor
- :type delay_factor: int
:param max_loops: Controls the wait time in conjunction with the delay_factor
- (default: 20)
"""
delay_factor = self.select_delay_factor(delay_factor)
+
+ # Revert telnet_login back to old speeds/delays
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
+
time.sleep(1 * delay_factor)
- output = ''
- return_msg = ''
+ output = ""
+ return_msg = ""
i = 1
while i <= max_loops:
try:
@@ -571,49 +818,70 @@ def telnet_login(self, pri_prompt_terminator=r'(? None:
+ """
+ In case of an exception happening during `session_preparation()` Netmiko should
+ gracefully clean-up after itself. This might be challenging for library users
+ to do since they do not have a reference to the object. This is possibly related
+ to threads used in Paramiko.
+ """
+ try:
+ self.session_preparation()
+ except Exception:
+ self.disconnect()
+ raise
+
+ def session_preparation(self) -> None:
"""
Prepare the session after the connection has been established
@@ -621,69 +889,82 @@ def session_preparation(self):
early on in the session.
In general, it should include:
- self._test_channel_read()
+ self._test_channel_read(pattern=r"some_pattern")
self.set_base_prompt()
- self.disable_paging()
self.set_terminal_width()
- self.clear_buffer()
+ self.disable_paging()
"""
self._test_channel_read()
self.set_base_prompt()
- self.disable_paging()
self.set_terminal_width()
-
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.disable_paging()
- def _use_ssh_config(self, dict_arg):
- """Update SSH connection parameters based on contents of SSH 'config' file.
+ def _use_ssh_config(self, dict_arg: Dict[str, Any]) -> Dict[str, Any]:
+ """Update SSH connection parameters based on contents of SSH config file.
:param dict_arg: Dictionary of SSH connection parameters
- :type dict_arg: dict
"""
connect_dict = dict_arg.copy()
# Use SSHConfig to generate source content.
+ assert self.ssh_config_file is not None
full_path = path.abspath(path.expanduser(self.ssh_config_file))
+ source: Union[paramiko.config.SSHConfigDict, Dict[str, Any]]
if path.exists(full_path):
ssh_config_instance = paramiko.SSHConfig()
- with io.open(full_path, "rt", encoding='utf-8') as f:
+ with io.open(full_path, "rt", encoding="utf-8") as f:
ssh_config_instance.parse(f)
source = ssh_config_instance.lookup(self.host)
else:
source = {}
+ # Keys get normalized to lower-case
+ proxy: Optional[paramiko.proxy.ProxyCommand]
if "proxycommand" in source:
- proxy = paramiko.ProxyCommand(source['proxycommand'])
- elif "ProxyCommand" in source:
- proxy = paramiko.ProxyCommand(source['ProxyCommand'])
+ proxy = paramiko.ProxyCommand(source["proxycommand"])
+ elif "proxyjump" in source:
+ hops = list(reversed(source["proxyjump"].split(",")))
+ if len(hops) > 1:
+ raise ValueError(
+ "ProxyJump with more than one proxy server is not supported."
+ )
+ port = source.get("port", self.port)
+ host = source.get("hostname", self.host)
+ # -F {full_path} forces the continued use of the same SSH config file
+ cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0])
+ proxy = paramiko.ProxyCommand(cmd)
else:
proxy = None
# Only update 'hostname', 'sock', 'port', and 'username'
# For 'port' and 'username' only update if using object defaults
- if connect_dict['port'] == 22:
- connect_dict['port'] = int(source.get('port', self.port))
- if connect_dict['username'] == '':
- connect_dict['username'] = source.get('username', self.username)
+ if connect_dict["port"] == 22:
+ connect_dict["port"] = int(source.get("port", self.port))
+ if connect_dict["username"] == "":
+ connect_dict["username"] = source.get("user", self.username)
if proxy:
- connect_dict['sock'] = proxy
- connect_dict['hostname'] = source.get('hostname', self.host)
+ connect_dict["sock"] = proxy
+ connect_dict["hostname"] = source.get("hostname", self.host)
return connect_dict
- def _connect_params_dict(self):
+ def _connect_params_dict(self) -> Dict[str, Any]:
"""Generate dictionary of Paramiko connection parameters."""
conn_dict = {
- 'hostname': self.host,
- 'port': self.port,
- 'username': self.username,
- 'password': self.password,
- 'look_for_keys': self.use_keys,
- 'allow_agent': self.allow_agent,
- 'key_filename': self.key_file,
- 'timeout': self.timeout,
+ "hostname": self.host,
+ "port": self.port,
+ "username": self.username,
+ "password": self.password,
+ "look_for_keys": self.use_keys,
+ "allow_agent": self.allow_agent,
+ "key_filename": self.key_file,
+ "pkey": self.pkey,
+ "passphrase": self.passphrase,
+ "disabled_algorithms": self.disabled_algorithms,
+ "timeout": self.conn_timeout,
+ "auth_timeout": self.auth_timeout,
+ "banner_timeout": self.banner_timeout,
+ "sock": self.sock,
}
# Check if using SSH 'config' file mainly for SSH proxy support
@@ -691,19 +972,14 @@ def _connect_params_dict(self):
conn_dict = self._use_ssh_config(conn_dict)
return conn_dict
- def _sanitize_output(self, output, strip_command=False, command_string=None,
- strip_prompt=False):
- """Strip out command echo, trailing router prompt and ANSI escape codes.
-
- :param output: Output from a remote network device
- :type output: unicode string
-
- :param strip_command:
- :type strip_command:
- """
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- output = self.normalize_linefeeds(output)
+ def _sanitize_output(
+ self,
+ output: str,
+ strip_command: bool = False,
+ command_string: Optional[str] = None,
+ strip_prompt: bool = False,
+ ) -> str:
+ """Strip out command echo and trailing router prompt."""
if strip_command and command_string:
command_string = self.normalize_linefeeds(command_string)
output = self.strip_command(command_string, output)
@@ -711,73 +987,125 @@ def _sanitize_output(self, output, strip_command=False, command_string=None,
output = self.strip_prompt(output)
return output
- def establish_connection(self, width=None, height=None):
+ def establish_connection(self, width: int = 511, height: int = 1000) -> None:
"""Establish SSH connection to the network device
- Timeout will generate a NetMikoTimeoutException
- Authentication failure will generate a NetMikoAuthenticationException
-
- width and height are needed for Fortinet paging setting.
+ Timeout will generate a NetmikoTimeoutException
+ Authentication failure will generate a NetmikoAuthenticationException
- :param width: Specified width of the VT100 terminal window
+ :param width: Specified width of the VT100 terminal window (default: 511)
:type width: int
- :param height: Specified height of the VT100 terminal window
+ :param height: Specified height of the VT100 terminal window (default: 1000)
:type height: int
"""
- if self.protocol == 'telnet':
- self.remote_conn = telnetlib.Telnet(self.host, port=self.port, timeout=self.timeout)
+ self.channel: Channel
+ if self.protocol == "telnet":
+ self.remote_conn = telnetlib.Telnet(
+ self.host, port=self.port, timeout=self.timeout
+ )
+ # Migrating communication to channel class
+ self.channel = TelnetChannel(conn=self.remote_conn, encoding=self.encoding)
self.telnet_login()
- elif self.protocol == 'serial':
+ elif self.protocol == "serial":
self.remote_conn = serial.Serial(**self.serial_settings)
+ self.channel = SerialChannel(conn=self.remote_conn, encoding=self.encoding)
self.serial_login()
- elif self.protocol == 'ssh':
+ elif self.protocol == "ssh":
ssh_connect_params = self._connect_params_dict()
+ self.remote_conn_pre: Optional[paramiko.SSHClient]
self.remote_conn_pre = self._build_ssh_client()
# initiate SSH connection
try:
self.remote_conn_pre.connect(**ssh_connect_params)
- except socket.error:
+ except socket.error as conn_error:
self.paramiko_cleanup()
- msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
- device_type=self.device_type, ip=self.host, port=self.port)
- raise NetMikoTimeoutException(msg)
+ msg = f"""TCP connection to device failed.
+
+Common causes of this problem are:
+1. Incorrect hostname or IP address.
+2. Wrong TCP port.
+3. Intermediate firewall blocking access.
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
+ # Handle DNS failures separately
+ if "Name or service not known" in str(conn_error):
+ msg = (
+ f"DNS failure--the hostname you provided was not resolvable "
+ f"in DNS: {self.host}:{self.port}"
+ )
+
+ msg = msg.lstrip()
+ raise NetmikoTimeoutException(msg)
except paramiko.ssh_exception.AuthenticationException as auth_err:
self.paramiko_cleanup()
- msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
- device_type=self.device_type, ip=self.host, port=self.port)
+ msg = f"""Authentication to device failed.
+
+Common causes of this problem are:
+1. Invalid username and password
+2. Incorrect SSH-key file
+3. Connecting to the wrong device
+
+Device settings: {self.device_type} {self.host}:{self.port}
+
+"""
+
msg += self.RETURN + str(auth_err)
- raise NetMikoAuthenticationException(msg)
+ raise NetmikoAuthenticationException(msg)
+ except paramiko.ssh_exception.SSHException as e:
+ self.paramiko_cleanup()
+ if "No existing session" in str(e):
+ msg = (
+ "Paramiko: 'No existing session' error: "
+ "try increasing 'conn_timeout' to 15 seconds or larger."
+ )
+ raise NetmikoTimeoutException(msg)
+ else:
+ msg = f"""
+A paramiko SSHException occurred during connection creation:
+
+{str(e)}
+
+"""
+ raise NetmikoTimeoutException(msg)
if self.verbose:
- print("SSH connection established to {0}:{1}".format(self.host, self.port))
+ print(f"SSH connection established to {self.host}:{self.port}")
# Use invoke_shell to establish an 'interactive session'
- if width and height:
- self.remote_conn = self.remote_conn_pre.invoke_shell(term='vt100', width=width,
- height=height)
- else:
- self.remote_conn = self.remote_conn_pre.invoke_shell()
+ self.remote_conn = self.remote_conn_pre.invoke_shell(
+ term="vt100", width=width, height=height
+ )
self.remote_conn.settimeout(self.blocking_timeout)
if self.keepalive:
+ assert isinstance(self.remote_conn.transport, paramiko.Transport)
self.remote_conn.transport.set_keepalive(self.keepalive)
+
+ # Migrating communication to channel class
+ self.channel = SSHChannel(conn=self.remote_conn, encoding=self.encoding)
+
self.special_login_handler()
if self.verbose:
print("Interactive SSH session established")
- return ""
- def _test_channel_read(self, count=40, pattern=""):
+ return None
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
"""Try to read the channel (generally post login) verify you receive data back.
:param count: the number of times to check the channel for data
- :type count: int
:param pattern: Regular expression pattern used to determine end of channel read
- :type pattern: str
"""
- def _increment_delay(main_delay, increment=1.1, maximum=8):
+
+ def _increment_delay(
+ main_delay: float, increment: float = 1.1, maximum: int = 8
+ ) -> float:
"""Increment sleep time to a maximum value."""
main_delay = main_delay * increment
if main_delay >= maximum:
@@ -786,29 +1114,26 @@ def _increment_delay(main_delay, increment=1.1, maximum=8):
i = 0
delay_factor = self.select_delay_factor(delay_factor=0)
- main_delay = delay_factor * .1
+
+ if pattern:
+ return self.read_until_pattern(pattern=pattern, read_timeout=20)
+
+ main_delay = delay_factor * 0.1
time.sleep(main_delay * 10)
new_data = ""
while i <= count:
- new_data += self._read_channel_timing()
- if new_data and pattern:
- if re.search(pattern, new_data):
- break
- elif new_data:
- break
- else:
- self.write_channel(self.RETURN)
+ new_data += self.read_channel_timing()
+ if new_data:
+ return new_data
+
+ self.write_channel(self.RETURN)
main_delay = _increment_delay(main_delay)
time.sleep(main_delay)
i += 1
- # check if data was ever present
- if new_data:
- return ""
- else:
- raise NetMikoTimeoutException("Timed out waiting for data")
+ raise NetmikoTimeoutException("Timed out waiting for data")
- def _build_ssh_client(self):
+ def _build_ssh_client(self) -> paramiko.SSHClient:
"""Prepare for Paramiko SSH connection."""
# Create instance of SSHClient object
remote_conn_pre = paramiko.SSHClient()
@@ -823,7 +1148,7 @@ def _build_ssh_client(self):
remote_conn_pre.set_missing_host_key_policy(self.key_policy)
return remote_conn_pre
- def select_delay_factor(self, delay_factor):
+ def select_delay_factor(self, delay_factor: float) -> float:
"""
Choose the greater of delay_factor or self.global_delay_factor (default).
In fast_cli choose the lesser of delay_factor of self.global_delay_factor.
@@ -832,7 +1157,7 @@ def select_delay_factor(self, delay_factor):
:type delay_factor: int
"""
if self.fast_cli:
- if delay_factor <= self.global_delay_factor:
+ if delay_factor and delay_factor <= self.global_delay_factor:
return delay_factor
else:
return self.global_delay_factor
@@ -842,191 +1167,310 @@ def select_delay_factor(self, delay_factor):
else:
return self.global_delay_factor
- def special_login_handler(self, delay_factor=1):
- """Handler for devices like WLC, Avaya ERS that throw up characters prior to login."""
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handler for devices like WLC, Extreme ERS that throw up characters prior to login."""
pass
- def disable_paging(self, command="terminal length 0", delay_factor=1):
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
"""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
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
"""
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(delay_factor * .1)
- self.clear_buffer()
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
command = self.normalize_cmd(command)
log.debug("In disable_paging")
- log.debug("Command: {0}".format(command))
+ log.debug(f"Command: {command}")
self.write_channel(command)
- output = self.read_until_prompt()
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- log.debug("{0}".format(output))
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(
+ pattern=re.escape(command.strip()), read_timeout=20
+ )
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern, read_timeout=20)
+ else:
+ output = self.read_until_prompt()
+ log.debug(f"{output}")
log.debug("Exiting disable_paging")
return output
- def set_terminal_width(self, command="", delay_factor=1):
+ def set_terminal_width(
+ self,
+ command: str = "",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = False,
+ pattern: Optional[str] = None,
+ ) -> str:
"""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
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
"""
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
if not command:
return ""
- delay_factor = self.select_delay_factor(delay_factor)
command = self.normalize_cmd(command)
self.write_channel(command)
- output = self.read_until_prompt()
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
+
+ # Avoid cmd_verify here as terminal width must be set before doing cmd_verify
+ if cmd_verify and self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ elif pattern:
+ output = self.read_until_pattern(pattern=pattern)
+ else:
+ output = self.read_until_prompt()
return output
- def set_base_prompt(self, pri_prompt_terminator='#',
- alt_prompt_terminator='>', delay_factor=1):
+ # 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),
+ reraise=True,
+ )
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt
Used as delimiter for stripping of trailing prompt in output.
Should be set to something that is general and applies in multiple contexts. For Cisco
- devices this will be set to router hostname (i.e. prompt without '>' or '#').
+ devices this will be set to router hostname (i.e. prompt without > or #).
This will be set on entering user exec or privileged exec on Cisco, but not when
entering/exiting config mode.
:param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
- :type pri_prompt_terminator: str
:param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
- :type alt_prompt_terminator: str
:param delay_factor: See __init__: global_delay_factor
- :type delay_factor: int
+
+ :param pattern: Regular expression pattern to search for in find_prompt() call
"""
- prompt = self.find_prompt(delay_factor=delay_factor)
+ if pattern is None:
+ if pri_prompt_terminator and alt_prompt_terminator:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ pattern = rf"({pri_term}|{alt_term})"
+ elif pri_prompt_terminator:
+ pattern = re.escape(pri_prompt_terminator)
+ elif alt_prompt_terminator:
+ pattern = re.escape(alt_prompt_terminator)
+
+ if pattern:
+ prompt = self.find_prompt(delay_factor=delay_factor, pattern=pattern)
+ else:
+ prompt = self.find_prompt(delay_factor=delay_factor)
+
if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
- raise ValueError("Router prompt not found: {0}".format(repr(prompt)))
+ raise ValueError(f"Router prompt not found: {repr(prompt)}")
# Strip off trailing terminator
self.base_prompt = prompt[:-1]
return self.base_prompt
- def find_prompt(self, delay_factor=1):
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
"""Finds the current network device prompt, last line only.
:param delay_factor: See __init__: global_delay_factor
:type delay_factor: int
+
+ :param pattern: Regular expression pattern to determine whether prompt is valid
"""
delay_factor = self.select_delay_factor(delay_factor)
+ sleep_time = delay_factor * 0.25
self.clear_buffer()
self.write_channel(self.RETURN)
- time.sleep(delay_factor * 0.1 )
- # Initial attempt to get prompt
- prompt = self.read_channel()
- vxr_pattern = "last login"
- if vxr_pattern in prompt.lower():
- time.sleep((delay_factor * 0.1)+3)
- prompt = self.read_channel()
- autocommand_pattern = "executing autocommand"
- if autocommand_pattern in prompt.lower():
- time.sleep((delay_factor * 0.1)+5)
- prompt=self.read_channel()
- cxr_pattern = "last switch-over"
- if cxr_pattern in prompt.lower():
- time.sleep((delay_factor * 0.1)+3)
- prompt = self.read_channel()
- if self.ansi_escape_codes:
- prompt = self.strip_ansi_escape_codes(prompt)
- # Check if the only thing you received was a newline
- count = 0
- prompt = prompt.strip()
- while count <= 10 and not prompt:
- log.debug("count = {}".format(count))
+ if pattern:
+ try:
+ prompt = self.read_until_pattern(pattern=pattern)
+ except ReadTimeout:
+ pass
+ else:
+ # Initial read
+ time.sleep(sleep_time)
prompt = self.read_channel().strip()
- if prompt:
- if self.ansi_escape_codes:
- prompt = self.strip_ansi_escape_codes(prompt).strip()
- else:
- t = 0
- while t <= 60:
- t = t +15
- time.sleep(15)
+
+ count = 0
+ while count <= 12 and not prompt:
+ if not prompt:
+ self.write_channel(self.RETURN)
+ time.sleep(sleep_time)
prompt = self.read_channel().strip()
- if prompt:
- if self.ansi_escape_codes:
- prompt = self.strip_ansi_escape_codes(prompt).strip()
- break
- self.write_channel(self.RETURN)
- time.sleep(delay_factor * .1)
- count += 1
+ if sleep_time <= 3:
+ # Double the sleep_time when it is small
+ sleep_time *= 2
+ else:
+ sleep_time += 1
+ count += 1
# If multiple lines in the output take the last line
- prompt = self.normalize_linefeeds(prompt)
prompt = prompt.split(self.RESPONSE_RETURN)[-1]
prompt = prompt.strip()
- if not prompt:
- raise ValueError("Unable to find prompt: {}".format(prompt))
- time.sleep(delay_factor * .1)
self.clear_buffer()
+ if not prompt:
+ raise ValueError(f"Unable to find prompt: {prompt}")
+ log.debug(f"[find_prompt()]: prompt is {prompt}")
return prompt
- def clear_buffer(self):
+ def clear_buffer(
+ self,
+ backoff: bool = True,
+ backoff_max: float = 3.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
"""Read any data available in the channel."""
- self.read_channel()
- def send_command_timing(self, command_string, delay_factor=1, max_loops=150,
- strip_prompt=True, strip_command=True, normalize=True,
- use_textfsm=False):
+ if delay_factor is None:
+ delay_factor = self.global_delay_factor
+ sleep_time = 0.1 * delay_factor
+
+ output = ""
+ for _ in range(10):
+ time.sleep(sleep_time)
+ data = self.read_channel()
+ data = self.strip_ansi_escape_codes(data)
+ output += data
+ if not data:
+ break
+ # Double sleep time each time we detect data
+ log.debug("Clear buffer detects data in the channel")
+ if backoff:
+ sleep_time *= 2
+ sleep_time = backoff_max if sleep_time >= backoff_max else sleep_time
+ return output
+
+ def command_echo_read(self, cmd: str, read_timeout: float) -> str:
+
+ # Make sure you read until you detect the command echo (avoid getting out of sync)
+ new_data = self.read_until_pattern(
+ pattern=re.escape(cmd), read_timeout=read_timeout
+ )
+
+ # There can be echoed prompts that haven't been cleared before the cmd echo
+ # this can later mess up the trailing prompt pattern detection. Clear this out.
+ lines = new_data.split(cmd)
+ if len(lines) == 2:
+ # lines[-1] should realistically just be the null string
+ new_data = f"{cmd}{lines[-1]}"
+ else:
+ # cmd exists in the output multiple times? Just retain the original output
+ pass
+ return new_data
+
+ @select_cmd_verify
+ def send_command_timing(
+ self,
+ command_string: str,
+ last_read: float = 2.0,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = False,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
"""Execute command_string on the SSH channel using a delay-based mechanism. Generally
used for show commands.
:param command_string: The command to be executed on the remote device.
- :type command_string: str
- :param delay_factor: Multiplying factor used to adjust delays (default: 1).
- :type delay_factor: int or float
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
- :param max_loops: Controls wait time in conjunction with delay_factor. Will default to be
- based upon self.timeout.
- :type max_loops: int
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
:param strip_prompt: Remove the trailing router prompt from the output (default: True).
- :type strip_prompt: bool
:param strip_command: Remove the echo of the command from the output (default: True).
- :type strip_command: bool
:param normalize: Ensure the proper enter is sent at end of command (default: True).
- :type normalize: bool
:param use_textfsm: Process command output through TextFSM template (default: False).
- :type normalize: bool
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: False).
"""
- output = ''
- delay_factor = self.select_delay_factor(delay_factor)
- self.clear_buffer()
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ output = ""
+ new_data = ""
if normalize:
command_string = self.normalize_cmd(command_string)
-
self.write_channel(command_string)
- output = self._read_channel_timing(delay_factor=delay_factor, max_loops=max_loops)
- output = self._sanitize_output(output, strip_command=strip_command,
- command_string=command_string, strip_prompt=strip_prompt)
- if use_textfsm:
- output = get_structured_data(output, platform=self.device_type,
- command=command_string.strip())
+
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+ output += new_data
+ output += self.read_channel_timing(
+ last_read=last_read, read_timeout=read_timeout
+ )
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_data = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_data
+
+ def _send_command_timing_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command_timing` method that always returns a
+ string"""
+ output = self.send_command_timing(*args, **kwargs)
+ assert isinstance(output, str)
return output
- def strip_prompt(self, a_string):
+ def strip_prompt(self, a_string: str) -> str:
"""Strip the trailing router prompt from the output.
:param a_string: Returned string from device
@@ -1034,144 +1478,328 @@ def strip_prompt(self, a_string):
"""
response_list = a_string.split(self.RESPONSE_RETURN)
last_line = response_list[-1]
+
if self.base_prompt in last_line:
return self.RESPONSE_RETURN.join(response_list[:-1])
else:
return a_string
- def send_command(self, command_string, expect_string=None,
- delay_factor=1, max_loops=500, auto_find_prompt=True,
- strip_prompt=True, strip_command=True, normalize=True,
- use_textfsm=False):
+ def _first_line_handler(self, data: str, search_pattern: str) -> Tuple[str, bool]:
+ """
+ In certain situations the first line will get repainted which causes a false
+ match on the terminating pattern.
+
+ Filter this out.
+
+ returns a tuple of (data, first_line_processed)
+
+ Where data is the original data potentially with the first line modified
+ and the first_line_processed is a flag indicating that we have handled the
+ first line.
+ """
+ try:
+ # First line is the echo line containing the command. In certain situations
+ # it gets repainted and needs filtered
+ lines = data.split(self.RETURN)
+ first_line = lines[0]
+ if BACKSPACE_CHAR in first_line:
+ pattern = search_pattern + r".*$"
+ first_line = re.sub(pattern, repl="", string=first_line)
+ lines[0] = first_line
+ data = self.RETURN.join(lines)
+ return (data, True)
+ except IndexError:
+ return (data, False)
+
+ def _prompt_handler(self, auto_find_prompt: bool) -> str:
+ if auto_find_prompt:
+ try:
+ prompt = self.find_prompt()
+ except ValueError:
+ prompt = self.base_prompt
+ else:
+ prompt = self.base_prompt
+ return re.escape(prompt.strip())
+
+ @select_cmd_verify
+ def send_command(
+ self,
+ command_string: str,
+ expect_string: Optional[str] = None,
+ read_timeout: float = 10.0,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ auto_find_prompt: bool = True,
+ strip_prompt: bool = True,
+ strip_command: bool = True,
+ normalize: bool = True,
+ use_textfsm: bool = False,
+ textfsm_template: Optional[str] = None,
+ use_ttp: bool = False,
+ ttp_template: Optional[str] = None,
+ use_genie: bool = False,
+ cmd_verify: bool = True,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
"""Execute command_string on the SSH channel using a pattern-based mechanism. Generally
used for show commands. By default this method will keep waiting to receive data until the
network device prompt is detected. The current network device prompt will be determined
automatically.
:param command_string: The command to be executed on the remote device.
- :type command_string: str
:param expect_string: Regular expression pattern to use for determining end of output.
If left blank will default to being based on router prompt.
- :type expect_string: str
- :param delay_factor: Multiplying factor used to adjust delays (default: 1).
- :type delay_factor: int
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
- :param max_loops: Controls wait time in conjunction with delay_factor. Will default to be
- based upon self.timeout.
- :type max_loops: int
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
:param strip_prompt: Remove the trailing router prompt from the output (default: True).
- :type strip_prompt: bool
:param strip_command: Remove the echo of the command from the output (default: True).
- :type strip_command: bool
:param normalize: Ensure the proper enter is sent at end of command (default: True).
- :type normalize: bool
:param use_textfsm: Process command output through TextFSM template (default: False).
- :type normalize: bool
+
+ :param textfsm_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_ttp: Process command output through TTP template (default: False).
+
+ :param ttp_template: Name of template to parse output with; can be fully qualified
+ path, relative path, or name of file in current directory. (default: None).
+
+ :param use_genie: Process command output through PyATS/Genie parser (default: False).
+
+ :param cmd_verify: Verify command echo before proceeding (default: True).
"""
+
# Time to delay in each read loop
- loop_delay = .2
- config_large_msg = "This could be a few minutes if your config is large"
- # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
- # and delay_factor arguments for backwards compatibility).
- delay_factor = self.select_delay_factor(delay_factor)
- if delay_factor == 1 and max_loops == 500:
- # Default arguments are being used; use self.timeout instead
- max_loops = int(self.timeout / loop_delay)
- log.info("In send_command, global_delay:{}, delay_factor:{}, max_loops:{}".format(
- self.global_delay_factor, delay_factor, max_loops))
- # Find the current router prompt
- if expect_string is None:
- if auto_find_prompt:
- try:
- prompt = self.find_prompt(delay_factor=delay_factor)
- except ValueError:
- log.info("From send_command: ValueError encountered from find_prompt() is not re-raised")
- prompt = self.base_prompt
+ loop_delay = 0.025
+
+ if self.read_timeout_override:
+ read_timeout = self.read_timeout_override
+
+ if self.delay_factor_compat:
+ # For compatibility calculate the old equivalent read_timeout
+ # i.e. what it would have been in Netmiko 3.x
+ if delay_factor is None:
+ tmp_delay_factor = self.global_delay_factor
else:
- prompt = self.base_prompt
- search_pattern = re.escape(prompt.strip())
+ tmp_delay_factor = self.select_delay_factor(delay_factor)
+ compat_timeout = calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=tmp_delay_factor,
+ loop_delay=0.2,
+ old_timeout=self.timeout,
+ )
+ msg = f"""\n
+You have chosen to use Netmiko's delay_factor compatibility mode for
+send_command. This will revert Netmiko to behave similarly to how it
+did in Netmiko 3.x (i.e. to use delay_factor/global_delay_factor and
+max_loops).
+
+Using these parameters Netmiko has calculated an effective read_timeout
+of {compat_timeout} and will set the read_timeout to this value.
+
+Please convert your code to that new format i.e.:
+
+ net_connect.send_command(cmd, read_timeout={compat_timeout})
+
+And then disable delay_factor_compat.
+
+delay_factor_compat will be removed in Netmiko 5.x.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ # Override the read_timeout with Netmiko 3.x way :-(
+ read_timeout = compat_timeout
+
else:
+ # No need for two deprecation messages so only display this if not using
+ # delay_factor_compat
+ if delay_factor is not None or max_loops is not None:
+ msg = """\n
+Netmiko 4.x has deprecated the use of delay_factor/max_loops with
+send_command. You should convert all uses of delay_factor and max_loops
+over to read_timeout=x where x is the total number of seconds to wait
+before timing out.\n"""
+ warnings.warn(msg, DeprecationWarning)
+
+ if expect_string is not None:
search_pattern = expect_string
+ else:
+ search_pattern = self._prompt_handler(auto_find_prompt)
if normalize:
command_string = self.normalize_cmd(command_string)
- time.sleep(delay_factor * loop_delay)
- self.clear_buffer()
+ # Start the clock
+ start_time = time.time()
self.write_channel(command_string)
+ new_data = ""
- i = 1
- output = ''
- # Keep reading data until search_pattern is found or until max_loops is reached.
- while i <= max_loops:
- new_data = self.read_channel()
+ cmd = command_string.strip()
+ if cmd and cmd_verify:
+ new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
+
+ MAX_CHARS = 2_000_000
+ DEQUE_SIZE = 20
+ output = ""
+ # Check only the past N-reads. This is for the case where the output is
+ # very large (i.e. searching a very large string for a pattern a whole bunch of times)
+ past_n_reads: Deque[str] = deque(maxlen=DEQUE_SIZE)
+ first_line_processed = False
+
+ # Keep reading data until search_pattern is found or until read_timeout
+ while time.time() - start_time < read_timeout:
if new_data:
- if self.ansi_escape_codes:
- new_data = self.strip_ansi_escape_codes(new_data)
output += new_data
- try:
- lines = output.split(self.RETURN)
- first_line = lines[0]
- # First line is the echo line containing the command. In certain situations
- # it gets repainted and needs filtered
- if BACKSPACE_CHAR in first_line:
- pattern = search_pattern + r'.*$'
- first_line = re.sub(pattern, repl='', string=first_line)
- lines[0] = first_line
- output = self.RETURN.join(lines)
- except IndexError:
- pass
- if re.search(search_pattern, output):
- break
-
- if re.search(config_large_msg, output):
- output = self.send_command(command_string=self.RETURN, \
- auto_find_prompt=False, strip_prompt=False, strip_command=False,)
- output += self.read_channel()
+ past_n_reads.append(new_data)
+
+ # Case where we haven't processed the first_line yet (there is a potential issue
+ # in the first line (in cases where the line is repainted).
+ if not first_line_processed:
+ output, first_line_processed = self._first_line_handler(
+ output, search_pattern
+ )
+ # Check if we have already found our pattern
if re.search(search_pattern, output):
break
- else:
- time.sleep(delay_factor * loop_delay)
- i += 1
- else: # nobreak
- raise IOError("Search pattern never detected in send_command_expect: {},\
- pattern found was: {}".format(search_pattern, output))
-
- output = self._sanitize_output(output, strip_command=strip_command,
- command_string=command_string, strip_prompt=strip_prompt)
- if use_textfsm:
- output = get_structured_data(output, platform=self.device_type,
- command=command_string.strip())
+
+ else:
+ if len(output) <= MAX_CHARS:
+ if re.search(search_pattern, output):
+ break
+ else:
+ # Switch to deque mode if output is greater than MAX_CHARS
+ # Check if pattern is in the past n reads
+ if re.search(search_pattern, "".join(past_n_reads)):
+ break
+
+ time.sleep(loop_delay)
+ new_data = self.read_channel()
+
+ else: # nobreak
+ msg = f"""
+Pattern not detected: {repr(search_pattern)} in output.
+
+Things you might try to fix this:
+1. Explicitly set your pattern using the expect_string argument.
+2. Increase the read_timeout to a larger value.
+
+You can also look at the Netmiko session_log or debug log for more information.
+
+"""
+ raise ReadTimeout(msg)
+
+ output = self._sanitize_output(
+ output,
+ strip_command=strip_command,
+ command_string=command_string,
+ strip_prompt=strip_prompt,
+ )
+ return_val = structured_data_converter(
+ command=command_string,
+ raw_data=output,
+ platform=self.device_type,
+ use_textfsm=use_textfsm,
+ use_ttp=use_ttp,
+ use_genie=use_genie,
+ textfsm_template=textfsm_template,
+ ttp_template=ttp_template,
+ )
+ return return_val
+
+ def _send_command_str(self, *args: Any, **kwargs: Any) -> str:
+ """Wrapper for `send_command` method that always returns a string"""
+ output = self.send_command(*args, **kwargs)
+ assert isinstance(output, str)
return output
- def send_command_expect(self, *args, **kwargs):
- """Support previous name of send_command method.
+ def send_command_expect(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Support previous name of send_command method."""
+ return self.send_command(*args, **kwargs)
+
+ def _multiline_kwargs(self, **kwargs: Any) -> Dict[str, Any]:
+ strip_prompt = kwargs.get("strip_prompt", False)
+ kwargs["strip_prompt"] = strip_prompt
+ strip_command = kwargs.get("strip_command", False)
+ kwargs["strip_command"] = strip_command
+ return kwargs
+
+ def send_multiline(
+ self,
+ commands: Sequence[Union[str, List[str]]],
+ multiline: bool = True,
+ **kwargs: Any,
+ ) -> str:
+ """
+ commands should either be:
- :param args: Positional arguments to send to send_command()
- :type args: list
+ commands = [[cmd1, expect1], [cmd2, expect2], ...]]
+
+ Or
+
+ commands = [cmd1, cmd2, cmd3, ...]
+
+ Any expect_string that is a null-string will use pattern based on
+ device's prompt (unless expect_string argument is passed in via
+ kwargs.
- :param kwargs: Keyword arguments to send to send_command()
- :type kwargs: dict
"""
- return self.send_command(*args, **kwargs)
+ output = ""
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+
+ default_expect_string = kwargs.pop("expect_string", None)
+ if not default_expect_string:
+ auto_find_prompt = kwargs.get("auto_find_prompt", True)
+ default_expect_string = self._prompt_handler(auto_find_prompt)
+
+ if commands and isinstance(commands[0], str):
+ # If list of commands just send directly using default_expect_string (probably prompt)
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_str(
+ cmd, expect_string=default_expect_string, **kwargs
+ )
+ else:
+ # If list of lists, then first element is cmd and second element is expect_string
+ for cmd_item in commands:
+ assert not isinstance(cmd_item, str)
+ cmd, expect_string = cmd_item
+ if not expect_string:
+ expect_string = default_expect_string
+ output += self._send_command_str(
+ cmd, expect_string=expect_string, **kwargs
+ )
+ return output
+
+ def send_multiline_timing(
+ self, commands: Sequence[str], multiline: bool = True, **kwargs: Any
+ ) -> str:
+ if multiline:
+ kwargs = self._multiline_kwargs(**kwargs)
+ output = ""
+ for cmd in commands:
+ cmd = str(cmd)
+ output += self._send_command_timing_str(cmd, **kwargs)
+ return output
@staticmethod
- def strip_backspaces(output):
+ def strip_backspaces(output: str) -> str:
"""Strip any backspace characters out of the output.
:param output: Output obtained from a remote network device.
:type output: str
"""
- backspace_char = '\x08'
- return output.replace(backspace_char, '')
+ backspace_char = "\x08"
+ return output.replace(backspace_char, "")
- def strip_command(self, command_string, output):
+ def strip_command(self, command_string: str, output: str) -> str:
"""
Strip command_string from output string
@@ -1183,32 +1811,39 @@ def strip_command(self, command_string, output):
:param output: The returned output as a result of the command string sent to the device
:type output: str
"""
- backspace_char = '\x08'
+ backspace_char = "\x08"
# Check for line wrap (remove backspaces)
if backspace_char in output:
- output = output.replace(backspace_char, '')
+ output = output.replace(backspace_char, "")
+
+ # Juniper has a weird case where the echoed command will be " \n"
+ # i.e. there is an extra space there.
+ cmd = command_string.strip()
+ if output.startswith(cmd):
output_lines = output.split(self.RESPONSE_RETURN)
new_output = output_lines[1:]
return self.RESPONSE_RETURN.join(new_output)
else:
- command_length = len(command_string)
- return output[command_length:]
+ # command_string isn't there; do nothing
+ return output
- def normalize_linefeeds(self, a_string):
+ def normalize_linefeeds(self, a_string: str) -> str:
"""Convert `\r\r\n`,`\r\n`, `\n\r` to `\n.`
:param a_string: A string that may have non-normalized line feeds
i.e. output returned from device, or a device prompt
:type a_string: str
"""
- newline = re.compile('(\r\r\r\n|\r\r\n|\r\n|\n\r)')
+ newline = re.compile("(\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':
+ if self.RESPONSE_RETURN == "\n":
# Convert any remaining \r to \n
- return re.sub('\r', self.RESPONSE_RETURN, a_string)
+ return re.sub("\r", self.RESPONSE_RETURN, a_string)
+ else:
+ return a_string
- def normalize_cmd(self, command):
+ def normalize_cmd(self, command: str) -> str:
"""Normalize CLI commands to have a single trailing newline.
:param command: Command that may require line feed to be normalized
@@ -1218,44 +1853,71 @@ def normalize_cmd(self, command):
command += self.RETURN
return command
- def check_enable_mode(self, check_string=''):
+ def check_enable_mode(self, check_string: str = "") -> bool:
"""Check if in enable mode. Return boolean.
:param check_string: Identification of privilege mode from device
:type check_string: str
"""
self.write_channel(self.RETURN)
- output = self.read_until_prompt()
+ output = self.read_until_prompt(read_entire_line=True)
return check_string in output
- def enable(self, cmd='', pattern='ssword', re_flags=re.IGNORECASE):
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Enter enable mode.
:param cmd: Device command to enter enable mode
- :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
:param re_flags: Regular expression flags used in conjunction with pattern
- :type re_flags: int
"""
output = ""
- msg = "Failed to enter enable mode. Please ensure you pass " \
- "the 'secret' argument to ConnectHandler."
+ msg = (
+ "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_prompt_or_pattern(pattern=pattern, re_flags=re_flags)
- self.write_channel(self.normalize_cmd(self.secret))
- output += self.read_until_prompt()
- except NetMikoTimeoutException:
- raise ValueError(msg)
- if not self.check_enable_mode():
+ # 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
+ )
+ # 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:
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ except NetmikoTimeoutException:
raise ValueError(msg)
return output
- def exit_enable_mode(self, exit_command=''):
+ def exit_enable_mode(self, exit_command: str = "") -> str:
"""Exit enable mode.
:param exit_command: Command that exits the session from privileged mode
@@ -1269,7 +1931,7 @@ def exit_enable_mode(self, exit_command=''):
raise ValueError("Failed to exit enable mode.")
return output
- def check_config_mode(self, check_string='', pattern=''):
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
"""Checks if the device is in configuration mode or not.
:param check_string: Identification of configuration mode from the device
@@ -1281,12 +1943,14 @@ def check_config_mode(self, check_string='', pattern=''):
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()
+ output = self.read_channel_timing()
else:
output = self.read_until_pattern(pattern=pattern)
return check_string in output
- def config_mode(self, config_command='', pattern=''):
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
"""Enter into config_mode.
:param config_command: Configuration command to send to the device
@@ -1294,16 +1958,27 @@ def config_mode(self, config_command='', pattern=''):
:param pattern: Pattern to terminate reading of channel
:type pattern: str
+
+ :param re_flags: Regular expression flags
+ :type re_flags: RegexFlag
"""
- output = ''
+ output = ""
if not self.check_config_mode():
self.write_channel(self.normalize_cmd(config_command))
- output = self.read_until_pattern(pattern=pattern)
+ # 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(config_command.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
if not self.check_config_mode():
raise ValueError("Failed to enter configuration mode.")
return output
- def exit_config_mode(self, exit_config='', pattern=''):
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
"""Exit from configuration mode.
:param exit_config: Command to exit configuration mode
@@ -1312,16 +1987,26 @@ def exit_config_mode(self, exit_config='', pattern=''):
:param pattern: Pattern to terminate reading of channel
:type pattern: str
"""
- output = ''
+ output = ""
if self.check_config_mode():
self.write_channel(self.normalize_cmd(exit_config))
- output = self.read_until_pattern(pattern=pattern)
+ # 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_config.strip())
+ )
+ if pattern:
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
- log.debug("exit_config_mode: {0}".format(output))
+ log.debug(f"exit_config_mode: {output}")
return output
- def send_config_from_file(self, config_file=None, **kwargs):
+ def send_config_from_file(
+ self, config_file: Union[str, bytes, "PathLike[Any]"], **kwargs: Any
+ ) -> str:
"""
Send configuration commands down the SSH channel from a file.
@@ -1331,17 +2016,30 @@ def send_config_from_file(self, config_file=None, **kwargs):
**kwargs are passed to send_config_set method.
:param config_file: Path to configuration file to be sent to the device
- :type config_file: str
:param kwargs: params to be sent to send_config_set method
- :type kwargs: dict
"""
- with io.open(config_file, "rt", encoding='utf-8') as cfg_file:
- return self.send_config_set(cfg_file, **kwargs)
-
- 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):
+ with io.open(config_file, "rt", encoding="utf-8") as cfg_file:
+ commands = cfg_file.readlines()
+ return self.send_config_set(commands, **kwargs)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ *,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"#",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
"""
Send configuration commands down the SSH channel.
@@ -1351,53 +2049,139 @@ def send_config_set(self, config_commands=None, exit_config_mode=True, delay_fac
Automatically exits/enters configuration mode.
:param config_commands: Multiple configuration commands to be sent to the device
- :type config_commands: list or string
:param exit_config_mode: Determines whether or not to exit config mode after complete
- :type exit_config_mode: bool
- :param delay_factor: Factor to adjust delays
- :type delay_factor: int
+ :param delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
- :param max_loops: Controls wait time in conjunction with delay_factor (default: 150)
- :type max_loops: int
+ :param max_loops: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
:param strip_prompt: Determines whether or not to strip the prompt
- :type strip_prompt: bool
:param strip_command: Determines whether or not to strip the command
- :type strip_command: bool
+
+ :param read_timeout: Absolute timer to send to read_channel_timing. Should be rarely needed.
:param config_mode_command: The command to enter into config mode
- :type config_mode_command: str
+
+ :param cmd_verify: Whether or not to verify command echo for each command in config_set
+
+ :param enter_config_mode: Do you enter config mode before sending config commands
+
+ :param error_pattern: Regular expression pattern to detect config errors in the
+ output.
+
+ :param terminator: Regular expression pattern to use as an alternate terminator in certain
+ situations.
+
+ :param bypass_commands: Regular expression pattern indicating configuration commands
+ where cmd_verify is automatically disabled.
"""
- delay_factor = self.select_delay_factor(delay_factor)
+
+ if self.global_cmd_verify is not None:
+ cmd_verify = self.global_cmd_verify
+
+ if delay_factor is not None or max_loops is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ # Calculate an equivalent read_timeout (if using old settings)
+ # Eliminate in Netmiko 5.x
+ if read_timeout is None:
+ max_loops = 150 if max_loops is None else max_loops
+ delay_factor = 1.0 if delay_factor is None else delay_factor
+
+ # If delay_factor has been set, then look at global_delay_factor
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ read_timeout = calc_old_timeout(
+ max_loops=max_loops, delay_factor=delay_factor, loop_delay=0.1
+ )
+
+ if delay_factor is None:
+ delay_factor = self.select_delay_factor(0)
+ else:
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ if read_timeout is None:
+ read_timeout = 15
+ else:
+ read_timeout = read_timeout
+
if config_commands is None:
- return ''
- elif isinstance(config_commands, string_types):
+ return ""
+ elif isinstance(config_commands, str):
config_commands = (config_commands,)
- if not hasattr(config_commands, '__iter__'):
+ if not hasattr(config_commands, "__iter__"):
raise ValueError("Invalid argument passed into send_config_set")
+ if bypass_commands is None:
+ # Commands where cmd_verify is automatically disabled reg-ex logical-or
+ bypass_commands = r"^banner .*$"
+
+ # Set bypass_commands="" to force no-bypass (usually for testing)
+ bypass_detected = False
+ if bypass_commands:
+ bypass_detected = any(
+ [True for cmd in config_commands if re.search(bypass_commands, cmd)]
+ )
+ if bypass_detected:
+ cmd_verify = False
+
# Send config commands
- cfg_mode_args = (config_mode_command,) if config_mode_command else tuple()
- output = self.config_mode(*cfg_mode_args)
- for cmd in config_commands:
- self.write_channel(self.normalize_cmd(cmd))
- if self.fast_cli:
- pass
- else:
- time.sleep(delay_factor * .05)
- # Gather output
- output += self._read_channel_timing(delay_factor=delay_factor, max_loops=max_loops)
+ output = ""
+ if enter_config_mode:
+ if config_mode_command:
+ output += self.config_mode(config_mode_command)
+ else:
+ output += self.config_mode()
+
+ # Perform output gathering line-by-line (legacy way)
+ 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(read_timeout=read_timeout)
+
+ elif not cmd_verify:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+ time.sleep(delay_factor * 0.05)
+
+ # Gather the output incrementally due to error_pattern requirements
+ if error_pattern:
+ output += self.read_channel_timing(read_timeout=read_timeout)
+ 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(read_timeout=read_timeout)
+
+ else:
+ for cmd in config_commands:
+ self.write_channel(self.normalize_cmd(cmd))
+
+ # Make sure command is echoed
+ output += self.read_until_pattern(pattern=re.escape(cmd.strip()))
+
+ # Read until next prompt or terminator (#); the .*$ forces read of entire line
+ pattern = f"(?:{re.escape(self.base_prompt)}.*$|{terminator}.*$)"
+ output += self.read_until_pattern(pattern=pattern, re_flags=re.M)
+
+ 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)
- log.debug("{}".format(output))
+ log.debug(f"{output}")
return output
- def strip_ansi_escape_codes(self, string_buffer):
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
"""
Remove any ANSI (VT100) ESC codes from the output
@@ -1418,75 +2202,116 @@ def strip_ansi_escape_codes(self, string_buffer):
ESC[?6l Reset mode screen with options 640 x 200 monochrome (graphics)
ESC[?7l Disable line wrapping
ESC[2J Code erase display
- ESC[00;32m Color Green (30 to 37 are different colors) more general pattern is
- ESC[\d\d;\d\dm and ESC[\d\d;\d\d;\d\dm
+ ESC[00;32m Color Green (30 to 37 are different colors)
ESC[6n Get cursor position
+ ESC[1D Move cursor position leftward by x characters (1 in this case)
+ ESC[9999B Move cursor down N-lines (very large value is attempt to move to the
+ very bottom of the screen).
- HP ProCurve's, Cisco SG300, and F5 LTM's require this (possible others)
+ HP ProCurve and Cisco SG300 require this (possible others).
:param string_buffer: The string to be processed to remove ANSI escape codes
:type string_buffer: str
- """
- log.debug("In strip_ansi_escape_codes")
- log.debug("repr = {0}".format(repr(string_buffer)))
-
- code_position_cursor = chr(27) + r'\[\d+;\d+H'
- code_show_cursor = chr(27) + r'\[\?25h'
- code_next_line = chr(27) + r'E'
- code_erase_line_end = chr(27) + r'\[K'
- code_erase_line = chr(27) + r'\[2K'
- code_erase_start_line = chr(27) + r'\[K'
- code_enable_scroll = chr(27) + r'\[\d+;\d+r'
- code_form_feed = chr(27) + r'\[1L'
- code_carriage_return = chr(27) + r'\[1M'
- code_disable_line_wrapping = chr(27) + r'\[\?7l'
- code_reset_mode_screen_options = chr(27) + r'\[\?\d+l'
- code_reset_graphics_mode = chr(27) + r'\[00m'
- code_erase_display = chr(27) + r'\[2J'
- code_graphics_mode = chr(27) + r'\[\d\d;\d\dm'
- code_graphics_mode2 = chr(27) + r'\[\d\d;\d\d;\d\dm'
- code_get_cursor_position = chr(27) + r'\[6n'
- code_cursor_position = chr(27) + r'\[m'
- code_erase_display = chr(27) + r'\[J'
-
- code_set = [code_position_cursor, code_show_cursor, code_erase_line, code_enable_scroll,
- code_erase_start_line, code_form_feed, code_carriage_return,
- code_disable_line_wrapping, code_erase_line_end,
- code_reset_mode_screen_options, code_reset_graphics_mode,
- code_erase_display,
- code_graphics_mode, code_graphics_mode2, code_get_cursor_position,
- code_cursor_position, code_erase_display]
+ """ # noqa
+
+ code_position_cursor = chr(27) + r"\[\d+;\d+H"
+ code_show_cursor = chr(27) + r"\[\?25h"
+ code_next_line = chr(27) + r"E"
+ code_erase_line_end = chr(27) + r"\[K"
+ code_erase_line = chr(27) + r"\[2K"
+ code_erase_start_line = chr(27) + r"\[K"
+ code_enable_scroll = chr(27) + r"\[\d+;\d+r"
+ code_insert_line = chr(27) + r"\[(\d+)L"
+ code_carriage_return = chr(27) + r"\[1M"
+ code_disable_line_wrapping = chr(27) + r"\[\?7l"
+ code_reset_mode_screen_options = chr(27) + r"\[\?\d+l"
+ code_reset_graphics_mode = chr(27) + r"\[00m"
+ code_erase_display = chr(27) + r"\[2J"
+ code_erase_display_0 = chr(27) + r"\[J"
+ code_graphics_mode = chr(27) + r"\[\dm"
+ code_graphics_mode1 = chr(27) + r"\[\d\d;\d\dm"
+ code_graphics_mode2 = chr(27) + r"\[\d\d;\d\d;\d\dm"
+ code_graphics_mode3 = chr(27) + r"\[(3|4)\dm"
+ code_graphics_mode4 = chr(27) + r"\[(9|10)[0-7]m"
+ code_get_cursor_position = chr(27) + r"\[6n"
+ code_cursor_position = chr(27) + r"\[m"
+ code_attrs_off = chr(27) + r"\[0m"
+ code_reverse = chr(27) + r"\[7m"
+ code_cursor_left = chr(27) + r"\[\d+D"
+ code_cursor_forward = chr(27) + r"\[\d*C"
+ code_cursor_up = chr(27) + r"\[\d*A"
+ code_cursor_down = chr(27) + r"\[\d*B"
+ code_wrap_around = chr(27) + r"\[\?7h"
+ code_bracketed_paste_mode = chr(27) + r"\[\?2004h"
+
+ code_set = [
+ code_position_cursor,
+ code_show_cursor,
+ code_erase_line,
+ code_enable_scroll,
+ code_erase_start_line,
+ code_carriage_return,
+ code_disable_line_wrapping,
+ code_erase_line_end,
+ code_reset_mode_screen_options,
+ code_reset_graphics_mode,
+ code_erase_display,
+ code_graphics_mode,
+ code_graphics_mode1,
+ code_graphics_mode2,
+ code_graphics_mode3,
+ code_graphics_mode4,
+ code_get_cursor_position,
+ code_cursor_position,
+ code_erase_display,
+ code_erase_display_0,
+ code_attrs_off,
+ code_reverse,
+ code_cursor_left,
+ code_cursor_up,
+ code_cursor_down,
+ code_cursor_forward,
+ code_wrap_around,
+ code_bracketed_paste_mode,
+ ]
output = string_buffer
for ansi_esc_code in code_set:
- output = re.sub(ansi_esc_code, '', output)
+ output = re.sub(ansi_esc_code, "", output)
# CODE_NEXT_LINE must substitute with return
output = re.sub(code_next_line, self.RETURN, output)
- log.debug("new_output = {0}".format(output))
- log.debug("repr = {0}".format(repr(output)))
+ # Aruba and ProCurve switches can use code_insert_line for
+ insert_line_match = re.search(code_insert_line, output)
+ if insert_line_match:
+ # Substitute each insert_line with a new
+ count = int(insert_line_match.group(1))
+ output = re.sub(code_insert_line, count * self.RETURN, output)
return output
- def cleanup(self):
- """Any needed cleanup before closing connection."""
+ def cleanup(self, command: str = "") -> None:
+ """Logout of the session on the network device plus any additional cleanup."""
pass
-
- def paramiko_cleanup(self):
+
+ def paramiko_cleanup(self) -> None:
"""Cleanup Paramiko to try to gracefully handle SSH session ending."""
- self.remote_conn_pre.close()
+ if self.remote_conn_pre is not None:
+ self.remote_conn_pre.close()
del self.remote_conn_pre
- def disconnect(self):
- """Try to gracefully close the SSH connection."""
+ def disconnect(self) -> None:
+ """Try to gracefully close the session."""
try:
self.cleanup()
- if self.protocol == 'ssh':
+ if self.protocol == "ssh":
self.paramiko_cleanup()
- elif self.protocol == 'telnet':
+ elif self.protocol == "telnet":
+ assert isinstance(self.remote_conn, telnetlib.Telnet)
self.remote_conn.close()
- elif self.protocol == 'serial':
+ elif self.protocol == "serial":
+ assert isinstance(self.remote_conn, serial.Serial)
self.remote_conn.close()
except Exception:
# There have been race conditions observed on disconnect.
@@ -1494,17 +2319,55 @@ def disconnect(self):
finally:
self.remote_conn_pre = None
self.remote_conn = None
- if self._session_log is not None and not self._external_session_log:
- self._session_log.close()
+ if self.session_log:
+ self.session_log.close()
- def commit(self):
+ def commit(self) -> str:
"""Commit method for platforms that support this."""
raise AttributeError("Network device does not support 'commit()' method")
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Not Implemented"""
raise NotImplementedError
+ def run_ttp(
+ self,
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Optional[Dict[str, Any]] = None,
+ **kwargs: Any,
+ ) -> Any:
+ """
+ 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
+
+ :param res_kwargs: ``**res_kwargs`` arguments to pass to TTP result method
+
+ :param kwargs: any other ``**kwargs`` to use for TTP object instantiation
+
+ TTP template must have inputs defined together with below parameters.
+
+ :param method: name of Netmiko connection object method to call, default ``send_command``
+
+ :param kwargs: Netmiko connection object method arguments
+
+ :param commands: list of commands to collect
+
+ 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.
+ """
+ if res_kwargs is None:
+ res_kwargs = {}
+ return run_ttp_template(
+ connection=self, template=template, res_kwargs=res_kwargs, **kwargs
+ )
+
class TelnetConnection(BaseConnection):
pass
diff --git a/netmiko/broadcom/__init__.py b/netmiko/broadcom/__init__.py
new file mode 100644
index 000000000..615e33f6f
--- /dev/null
+++ b/netmiko/broadcom/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.broadcom.broadcom_icos_ssh import BroadcomIcosSSH
+
+
+__all__ = ["BroadcomIcosSSH"]
diff --git a/netmiko/broadcom/broadcom_icos_ssh.py b/netmiko/broadcom/broadcom_icos_ssh.py
new file mode 100644
index 000000000..216838914
--- /dev/null
+++ b/netmiko/broadcom/broadcom_icos_ssh.py
@@ -0,0 +1,47 @@
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class BroadcomIcosSSH(CiscoSSHConnection):
+ """
+ Implements support for Broadcom Icos devices.
+ Syntax its almost identical to Cisco IOS in most cases
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """Exit enable mode."""
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/brocade/__init__.py b/netmiko/brocade/__init__.py
index 6b3eb01ec..a244ca541 100644
--- a/netmiko/brocade/__init__.py
+++ b/netmiko/brocade/__init__.py
@@ -1,6 +1,3 @@
-from __future__ import unicode_literals
-from netmiko.brocade.brocade_nos_ssh import BrocadeNosSSH
-from netmiko.brocade.brocade_netiron import BrocadeNetironSSH
-from netmiko.brocade.brocade_netiron import BrocadeNetironTelnet
+from netmiko.brocade.brocade_fos_ssh import BrocadeFOSSSH
-__all__ = ['BrocadeNosSSH', 'BrocadeNetironSSH', 'BrocadeNetironTelnet']
+__all__ = ["BrocadeFOSSSH"]
diff --git a/netmiko/brocade/brocade_fastiron_ssh.py b/netmiko/brocade/brocade_fastiron_ssh.py
deleted file mode 100644
index dcaabea60..000000000
--- a/netmiko/brocade/brocade_fastiron_ssh.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from __future__ import unicode_literals
-import re
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class BrocadeFastironSSH(CiscoSSHConnection):
- """Brocade FastIron aka ICX support."""
- def session_preparation(self):
- """FastIron requires to be enable mode to disable paging."""
- self._test_channel_read()
- self.set_base_prompt()
- self.enable()
- self.disable_paging(command="skip-page-display")
-
- @staticmethod
- def normalize_linefeeds(a_string):
- """Convert '\r\n\r\n', '\r\r\n','\r\n', '\n\r' to '\n."""
- newline = re.compile(r'(\r\n\r\n|\r\r\n|\r\n|\n\r|\r)')
- return newline.sub('\n', a_string)
diff --git a/netmiko/brocade/brocade_fastiron_telnet.py b/netmiko/brocade/brocade_fastiron_telnet.py
deleted file mode 100644
index 746ae0b4b..000000000
--- a/netmiko/brocade/brocade_fastiron_telnet.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from __future__ import unicode_literals
-import re
-from netmiko.cisco_base_connection import CiscoBaseConnection
-
-
-class BrocadeFastironTelnet(CiscoBaseConnection):
- """Brocade FastIron aka ICX support."""
- def session_preparation(self):
- """FastIron requires to be enable mode to disable paging."""
- self._test_channel_read()
- self.set_base_prompt()
- self.enable()
- self.disable_paging(command="skip-page-display")
-
- @staticmethod
- def normalize_linefeeds(a_string):
- """Convert '\r\n\r\n', '\r\r\n','\r\n', '\n\r' to '\n."""
- newline = re.compile(r'(\r\n\r\n|\r\r\n|\r\n|\n\r|\r)')
- return newline.sub('\n', a_string)
-
- def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>',
- username_pattern=r"Username:", pwd_pattern=r"assword:",
- delay_factor=1, max_loops=60):
- """Telnet login. Can be username/password or just password."""
- super(BrocadeFastironTelnet, self).telnet_login(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- username_pattern=username_pattern,
- pwd_pattern=pwd_pattern,
- delay_factor=delay_factor,
- max_loops=max_loops)
-
- def _test_channel_read(self, count=40, pattern="", newline_format="\r"):
- super(BrocadeFastironTelnet, self)._test_channel_read(count=count,
- pattern=pattern,
- newline_format=newline_format)
-
- def find_prompt(self, delay_factor=1, newline_format="\r"):
- return super(BrocadeFastironTelnet, self).find_prompt(delay_factor=delay_factor,
- newline_format=newline_format)
-
- @staticmethod
- def normalize_cmd(command, newline_format="\r"):
- return super(BrocadeFastironTelnet,
- BrocadeFastironTelnet).normalize_cmd(command,
- newline_format=newline_format)
-
- def check_enable_mode(self, check_string='', newline_format="\r"):
- return super(BrocadeFastironTelnet, self).check_enable_mode(check_string=check_string,
- newline_format=newline_format)
-
- def check_config_mode(self, check_string=')#', pattern='', newline_format="\r"):
- return super(BrocadeFastironTelnet, self).check_config_mode(check_string=check_string,
- pattern=pattern,
- newline_format=newline_format)
diff --git a/netmiko/brocade/brocade_fos_ssh.py b/netmiko/brocade/brocade_fos_ssh.py
new file mode 100644
index 000000000..6eaa313d0
--- /dev/null
+++ b/netmiko/brocade/brocade_fos_ssh.py
@@ -0,0 +1,17 @@
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class BrocadeFOSSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Brocade Fabric OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
diff --git a/netmiko/brocade/brocade_netiron.py b/netmiko/brocade/brocade_netiron.py
deleted file mode 100644
index 153879cdb..000000000
--- a/netmiko/brocade/brocade_netiron.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class BrocadeNetironBase(CiscoSSHConnection):
- def save_config(self, cmd='write memory', confirm=False):
- """Save Config"""
- return super(BrocadeNetironBase, self).save_config(cmd=cmd, confirm=confirm)
-
-
-class BrocadeNetironSSH(BrocadeNetironBase):
- pass
-
-
-class BrocadeNetironTelnet(BrocadeNetironBase):
- 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(BrocadeNetironTelnet, self).__init__(*args, **kwargs)
diff --git a/netmiko/brocade/brocade_netiron_ssh.py b/netmiko/brocade/brocade_netiron_ssh.py
deleted file mode 100644
index cf65a56fd..000000000
--- a/netmiko/brocade/brocade_netiron_ssh.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class BrocadeNetironSSH(CiscoSSHConnection):
- pass
diff --git a/netmiko/brocade/brocade_netiron_telnet.py b/netmiko/brocade/brocade_netiron_telnet.py
deleted file mode 100644
index 2ee2cf404..000000000
--- a/netmiko/brocade/brocade_netiron_telnet.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoBaseConnection
-
-
-class BrocadeNetironTelnet(CiscoBaseConnection):
- """Brocade NetIron aka CER support."""
- def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>',
- username_pattern=r"Username:", pwd_pattern=r"assword:",
- delay_factor=1, max_loops=60):
- """Telnet login. Can be username/password or just password."""
- super(BrocadeNetironTelnet, self).telnet_login(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- username_pattern=username_pattern,
- pwd_pattern=pwd_pattern,
- delay_factor=delay_factor,
- max_loops=max_loops)
-
- def _test_channel_read(self, count=40, pattern="", newline_format="\r"):
- super(BrocadeNetironTelnet, self)._test_channel_read(count=count,
- pattern=pattern,
- newline_format=newline_format)
-
- def find_prompt(self, delay_factor=1, newline_format="\r"):
- return super(BrocadeNetironTelnet, self).find_prompt(delay_factor=delay_factor,
- newline_format=newline_format)
-
- @staticmethod
- def normalize_cmd(command, newline_format="\r"):
- return super(BrocadeNetironTelnet,
- BrocadeNetironTelnet).normalize_cmd(command,
- newline_format=newline_format)
-
- def check_enable_mode(self, check_string='', newline_format="\r"):
- return super(BrocadeNetironTelnet, self).check_enable_mode(check_string=check_string,
- newline_format=newline_format)
-
- def check_config_mode(self, check_string=')#', pattern='', newline_format="\r"):
- return super(BrocadeNetironTelnet, self).check_config_mode(check_string=check_string,
- pattern=pattern,
- newline_format=newline_format)
diff --git a/netmiko/brocade/brocade_nos_ssh.py b/netmiko/brocade/brocade_nos_ssh.py
deleted file mode 100644
index 4eb315b31..000000000
--- a/netmiko/brocade/brocade_nos_ssh.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""Support for Brocade NOS/VDX."""
-from __future__ import unicode_literals
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class BrocadeNosSSH(CiscoSSHConnection):
- """Support for Brocade NOS/VDX."""
- def enable(self, *args, **kwargs):
- """No enable mode on Brocade VDX."""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on Brocade VDX."""
- pass
-
- def special_login_handler(self, delay_factor=1):
- """Adding a delay after login."""
- delay_factor = self.select_delay_factor(delay_factor)
- self.write_channel(self.RETURN)
- time.sleep(1 * delay_factor)
-
- def save_config(self, cmd='copy running-config startup-config', confirm=True,
- confirm_response='y'):
- """Save Config for Brocade VDX."""
- return super(BrocadeNosSSH, self).save_config(cmd=cmd, confirm=confirm,
- confirm_response=confirm_response)
diff --git a/netmiko/calix/__init__.py b/netmiko/calix/__init__.py
index eda503df1..0cbf5f6d0 100644
--- a/netmiko/calix/__init__.py
+++ b/netmiko/calix/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.calix.calix_b6 import CalixB6SSH, CalixB6Telnet
-__all__ = ['CalixB6SSH', 'CalixB6Telnet']
+__all__ = ["CalixB6SSH", "CalixB6Telnet"]
diff --git a/netmiko/calix/calix_b6.py b/netmiko/calix/calix_b6.py
index c8b9b1d40..cfb2f83bf 100644
--- a/netmiko/calix/calix_b6.py
+++ b/netmiko/calix/calix_b6.py
@@ -1,71 +1,80 @@
"""Calix B6 SSH Driver for Netmiko"""
-from __future__ import unicode_literals
-
+from typing import Any
import time
from os import path
from paramiko import SSHClient
from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class SSHClient_noauth(SSHClient):
- """Set noauth when manually handling SSH authentication."""
- def _auth(self, username, *args):
- self._transport.auth_none(username)
- return
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.exceptions import NetmikoTimeoutException
class CalixB6Base(CiscoSSHConnection):
"""Common methods for Calix B6, both SSH and Telnet."""
- 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(CalixB6SSH, self).__init__(*args, **kwargs)
- def session_preparation(self):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> Any:
"""Prepare the session after the connection has been established."""
self.ansi_escape_codes = True
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
self.disable_paging()
- self.set_terminal_width(command="terminal width 511")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def special_login_handler(self, delay_factor=1):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
"""
Calix B6 presents with the following on login:
login as:
Password: ****
"""
- delay_factor = self.select_delay_factor(delay_factor)
- i = 0
- time.sleep(delay_factor * .25)
- output = ""
- while i <= 12:
- output = self.read_channel()
+ new_data = ""
+ time.sleep(0.1)
+ start = time.time()
+ login_timeout = 20
+ while time.time() - start < login_timeout:
+ output = self.read_channel() if not new_data else new_data
+ new_data = ""
if output:
- if 'login as:' in output:
+ if "login as:" in output:
+ assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
- elif 'Password:' in output:
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
break
- time.sleep(delay_factor * 0.5)
+ time.sleep(0.1)
else:
- self.write_channel(self.RETURN)
- time.sleep(delay_factor * 1)
- i += 1
-
- def check_config_mode(self, check_string=')#', pattern=''):
+ # No new data...sleep longer
+ time.sleep(0.5)
+ new_data = self.read_channel()
+ # If still no data, send an
+ if not new_data:
+ self.write_channel(self.RETURN)
+ else: # no-break
+ msg = """
+Login process failed to Calix B6 device. Unable to login in {login_timeout} seconds.
+"""
+ raise NetmikoTimeoutException(msg)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
"""Checks if the device is in configuration mode"""
- return super(CalixB6Base, self).check_config_mode(
- check_string=check_string)
+ return super().check_config_mode(check_string=check_string)
- def save_config(self, cmd='copy run start', confirm=False):
- return super(CalixB6Base, self).save_config(cmd=cmd, confirm=confirm)
+ def save_config(
+ self,
+ cmd: str = "copy run start",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
class CalixB6SSH(CalixB6Base):
@@ -74,12 +83,13 @@ class CalixB6SSH(CalixB6Base):
To make it work, we have to override the SSHClient _auth method and manually handle
the username/password.
"""
- def _build_ssh_client(self):
+
+ def _build_ssh_client(self) -> SSHClient:
"""Prepare for Paramiko SSH connection."""
# Create instance of SSHClient object
# If not using SSH keys, we use noauth
if not self.use_keys:
- remote_conn_pre = SSHClient_noauth()
+ remote_conn_pre: SSHClient = SSHClient_noauth()
else:
remote_conn_pre = SSHClient()
@@ -96,4 +106,5 @@ def _build_ssh_client(self):
class CalixB6Telnet(CalixB6Base):
"""Calix B6 Telnet Driver."""
+
pass
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..6c523a32b
--- /dev/null
+++ b/netmiko/cdot/cdot_cros_ssh.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# CDOT = Centre for Development of Telematics, India
+# CROS = CDOT Router OS
+# Script: cros_ssh.py
+# Author: Maloy Ghosh
+# Updated by Kirk Byers
+#
+# Purpose: Provide basic SSH connection to CROS based router products
+
+from typing import Optional, Union, Sequence, TextIO, Any
+import time
+import warnings
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class CdotCrosSSH(NoEnable, CiscoBaseConnection):
+ """Implement methods for interacting with CROS network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[#\$]")
+ self.set_base_prompt()
+ self._disable_complete_on_space()
+ self.set_terminal_width(command="screen-width 511", pattern=r"screen.width 511")
+ self.disable_paging(command="screen-length 0")
+ return
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
+ """Checks if device is in configuration mode"""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ and_quit: bool = True,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ 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 _disable_complete_on_space(self) -> str:
+ """
+ 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/centec/__init__.py b/netmiko/centec/__init__.py
new file mode 100644
index 000000000..8ca6d8130
--- /dev/null
+++ b/netmiko/centec/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.centec.centec_os import CentecOSSSH, CentecOSTelnet
+
+__all__ = ["CentecOSSSH", "CentecOSTelnet"]
diff --git a/netmiko/centec/centec_os.py b/netmiko/centec/centec_os.py
new file mode 100644
index 000000000..d1e1307f6
--- /dev/null
+++ b/netmiko/centec/centec_os.py
@@ -0,0 +1,28 @@
+"""Centec OS Support"""
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class CentecOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CentecOSSSH(CentecOSBase):
+
+ pass
+
+
+class CentecOSTelnet(CentecOSBase):
+
+ pass
diff --git a/netmiko/channel.py b/netmiko/channel.py
new file mode 100644
index 000000000..d7bf759e1
--- /dev/null
+++ b/netmiko/channel.py
@@ -0,0 +1,167 @@
+from typing import Any, Optional
+from abc import ABC, abstractmethod
+import paramiko
+import telnetlib
+import serial
+
+from netmiko.utilities import write_bytes
+from netmiko.netmiko_globals import MAX_BUFFER
+from netmiko.exceptions import ReadException, WriteException
+
+
+class Channel(ABC):
+ @abstractmethod
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Create the object."""
+ pass
+
+ # @abstractmethod
+ # def __repr__(self) -> str:
+ # """String representation of the object."""
+ # pass
+ #
+ # @abstractmethod
+ # def open(self, width: int = 511, height: int = 1000) -> None:
+ # """Create the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def close(self) -> None:
+ # """Close the underlying connection."""
+ # pass
+ #
+ # @abstractmethod
+ # def login(self) -> None:
+ # """Handle the channel login process for any channel that requires it."""
+ # pass
+
+ @abstractmethod
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ pass
+
+ @abstractmethod
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ pass
+
+ @abstractmethod
+ def write_channel(self, out_data: str) -> None:
+ """Write data down the channel."""
+ pass
+
+ # @abstractmethod
+ # def is_alive(self) -> bool:
+ # """Is the channel alive."""
+ # pass
+
+
+class SSHChannel(Channel):
+ def __init__(self, conn: Optional[paramiko.Channel], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.sendall(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ if self.remote_conn.recv_ready():
+ outbuf = self.remote_conn.recv(MAX_BUFFER)
+ if len(outbuf) == 0:
+ raise ReadException("Channel stream closed by remote device.")
+ output += outbuf.decode("utf-8", "ignore")
+ return output
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while True:
+ new_output = self.read_buffer()
+ output += new_output
+ if new_output == "":
+ break
+ return output
+
+
+class TelnetChannel(Channel):
+ def __init__(self, conn: Optional[telnetlib.Telnet], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ raise NotImplementedError
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ return self.remote_conn.read_very_eager().decode("utf-8", "ignore")
+
+
+class SerialChannel(Channel):
+ def __init__(self, conn: Optional[serial.Serial], encoding: str) -> None:
+ """
+ Placeholder __init__ method so that reading and writing can be moved to the
+ channel class.
+ """
+ self.remote_conn = conn
+ # FIX: move encoding to GlobalState object?
+ self.encoding = encoding
+
+ def write_channel(self, out_data: str) -> None:
+ if self.remote_conn is None:
+ raise WriteException(
+ "Attempt to write data, but there is no active channel."
+ )
+ self.remote_conn.write(write_bytes(out_data, encoding=self.encoding))
+ self.remote_conn.flush()
+
+ def read_buffer(self) -> str:
+ """Single read of available data."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ if self.remote_conn.in_waiting > 0:
+ output = self.remote_conn.read(self.remote_conn.in_waiting).decode(
+ "utf-8", "ignore"
+ )
+ assert isinstance(output, str)
+ return output
+ else:
+ return ""
+
+ def read_channel(self) -> str:
+ """Read all of the available data from the channel."""
+ if self.remote_conn is None:
+ raise ReadException("Attempt to read, but there is no active channel.")
+ output = ""
+ while self.remote_conn.in_waiting > 0:
+ output += self.read_buffer()
+ return output
diff --git a/netmiko/checkpoint/__init__.py b/netmiko/checkpoint/__init__.py
index 56967ca39..a3503a0a2 100644
--- a/netmiko/checkpoint/__init__.py
+++ b/netmiko/checkpoint/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.checkpoint.checkpoint_gaia_ssh import CheckPointGaiaSSH
-__all__ = ['CheckPointGaiaSSH']
+__all__ = ["CheckPointGaiaSSH"]
diff --git a/netmiko/checkpoint/checkpoint_gaia_ssh.py b/netmiko/checkpoint/checkpoint_gaia_ssh.py
index 48b5fdca6..c16858828 100644
--- a/netmiko/checkpoint/checkpoint_gaia_ssh.py
+++ b/netmiko/checkpoint/checkpoint_gaia_ssh.py
@@ -1,34 +1,24 @@
-from __future__ import unicode_literals
-import time
+from netmiko.no_config import NoConfig
from netmiko.base_connection import BaseConnection
-class CheckPointGaiaSSH(BaseConnection):
+class CheckPointGaiaSSH(NoConfig, BaseConnection):
"""
Implements methods for communicating with Check Point Gaia
firewalls.
"""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""
Prepare the session after the connection has been established.
Set the base prompt for interaction ('>').
"""
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
self.disable_paging(command="set clienv rows 0")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def config_mode(self, config_command=''):
- """No config mode for Check Point devices."""
- return ''
-
- def exit_config_mode(self, exit_config=''):
- """No config mode for Check Point devices."""
- return ''
- def save_config(self, cmd='', confirm=True, confirm_response=''):
- """Not Implemented"""
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
raise NotImplementedError
diff --git a/netmiko/ciena/__init__.py b/netmiko/ciena/__init__.py
index a5d0237fe..1cfee9397 100644
--- a/netmiko/ciena/__init__.py
+++ b/netmiko/ciena/__init__.py
@@ -1,4 +1,7 @@
-from __future__ import unicode_literals
-from netmiko.ciena.ciena_saos_ssh import CienaSaosSSH
+from netmiko.ciena.ciena_saos import (
+ CienaSaosSSH,
+ CienaSaosTelnet,
+ CienaSaosFileTransfer,
+)
-__all__ = ['CienaSaosSSH']
+__all__ = ["CienaSaosSSH", "CienaSaosTelnet", "CienaSaosFileTransfer"]
diff --git a/netmiko/ciena/ciena_saos.py b/netmiko/ciena/ciena_saos.py
new file mode 100644
index 000000000..a0fd9ccaa
--- /dev/null
+++ b/netmiko/ciena/ciena_saos.py
@@ -0,0 +1,199 @@
+"""Ciena SAOS support."""
+from typing import Optional, Any
+import re
+import os
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+from netmiko.scp_handler import BaseFileTransfer
+
+
+class CienaSaosBase(NoEnable, NoConfig, BaseConnection):
+ """
+ Ciena SAOS support.
+
+ Implements methods for interacting Ciena Saos devices.
+ """
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="system shell session set more off")
+
+ def _enter_shell(self) -> str:
+ """Enter the Bourne Shell."""
+ output = self._send_command_str("diag shell", expect_string=r"[$#>]")
+ if "SHELL PARSER FAILURE" in output:
+ msg = "SCP support on Ciena SAOS requires 'diag shell' permissions"
+ raise ValueError(msg)
+ return output
+
+ def _return_cli(self) -> str:
+ """Return to the Ciena SAOS CLI."""
+ return self._send_command_str("exit", expect_string=r"[>]")
+
+ def save_config(
+ self,
+ cmd: str = "configuration save",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CienaSaosSSH(CienaSaosBase):
+ pass
+
+
+class CienaSaosTelnet(CienaSaosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class CienaSaosFileTransfer(BaseFileTransfer):
+ """Ciena SAOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ if file_system is None:
+ file_system = f"/tmp/users/{ssh_conn.username}"
+ return super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
+ """
+ Return space available on Ciena SAOS
+
+ Output should only have the file-system that matches {self.file_system}
+
+ Filesystem 1K-blocks Used Available Use% Mounted on
+ tmpfs 1048576 648 1047928 0% /tmp
+ """
+ remote_cmd = f"file vols -P {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ remote_output = remote_output.strip()
+ err_msg = (
+ f"Parsing error, unexpected output from {remote_cmd}:\n{remote_output}"
+ )
+
+ # First line is the header; file_system_line is the output we care about
+ header_line, filesystem_line = remote_output.splitlines()
+
+ filesystem, _, _, space_avail, *_ = header_line.split()
+ if "Filesystem" != filesystem or "Avail" not in space_avail:
+ # Filesystem 1K-blocks Used Available Use% Mounted on
+ raise ValueError(err_msg)
+
+ # Normalize output - in certain outputs ciena will line wrap (this fixes that)
+ # Strip the extra newline
+ # /dev/mapper/EN--VOL-config
+ # 4096 1476 2620 36% /etc/hosts
+ filesystem_line = re.sub(r"(^\S+$)\n", r"\1", filesystem_line, flags=re.M)
+
+ # Checks to make sure what was returned is what we expect
+ _, k_blocks, used, space_avail, _, _ = filesystem_line.split()
+ for integer_check in (k_blocks, used, space_avail):
+ try:
+ int(integer_check)
+ except ValueError:
+ raise ValueError(err_msg)
+
+ return int(space_avail) * 1024
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"file ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = re.escape(f"{self.file_system}/{self.dest_file}")
+ if "ERROR" in remote_out:
+ return False
+ elif re.search(search_string, remote_out):
+ return True
+ else:
+ raise ValueError("Unexpected output from check_file_exists")
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+
+ remote_file = f"{self.file_system}/{remote_file}"
+
+ if not remote_cmd:
+ remote_cmd = f"file ls -l {remote_file}"
+
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+
+ if "No such file or directory" in remote_out:
+ raise IOError("Unable to find file on remote system")
+
+ escape_file_name = re.escape(remote_file)
+ pattern = r"^.* ({}).*$".format(escape_file_name)
+ match = re.search(pattern, remote_out, flags=re.M)
+ if match:
+ # Format: -rw-r--r-- 1 pyclass wheel 12 Nov 5 19:07 /var/tmp/test3.txt
+ line = match.group(0)
+ file_size = line.split()[4]
+ return int(file_size)
+
+ raise ValueError(
+ "Search pattern not found for remote file size during SCP transfer."
+ )
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ """Calculate remote MD5 and returns the hash.
+
+ This command can be CPU intensive on the remote device.
+ """
+ if base_cmd == "":
+ base_cmd = "md5sum"
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+
+ self.ssh_ctl_chan._enter_shell()
+ dest_md5 = self.ssh_ctl_chan._send_command_str(
+ remote_md5_cmd, expect_string=r"[$#>]"
+ )
+ self.ssh_ctl_chan._return_cli()
+ dest_md5 = self.process_md5(dest_md5, pattern=r"([0-9a-f]+)\s+")
+ return dest_md5
+
+ def enable_scp(self, cmd: str = "system server scp enable") -> None:
+ return super().enable_scp(cmd=cmd)
+
+ def disable_scp(self, cmd: str = "system server scp disable") -> None:
+ return super().disable_scp(cmd=cmd)
diff --git a/netmiko/ciena/ciena_saos_ssh.py b/netmiko/ciena/ciena_saos_ssh.py
deleted file mode 100644
index 6d04fd20c..000000000
--- a/netmiko/ciena/ciena_saos_ssh.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""Ciena SAOS support."""
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class CienaSaosSSH(CiscoSSHConnection):
- """Ciena SAOS support."""
- def session_preparation(self):
- self._test_channel_read()
- self.set_base_prompt()
- self.disable_paging(command="system shell session set more off")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def enable(self, *args, **kwargs):
- pass
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
- """Not Implemented"""
- raise NotImplementedError
diff --git a/netmiko/cisco/__init__.py b/netmiko/cisco/__init__.py
index ad09d81af..1d32396e1 100644
--- a/netmiko/cisco/__init__.py
+++ b/netmiko/cisco/__init__.py
@@ -1,17 +1,39 @@
-from __future__ import unicode_literals
-from netmiko.cisco.cisco_ios import CiscoIosBase, CiscoIosSSH, CiscoIosTelnet, CiscoIosSerial
+from netmiko.cisco.cisco_ios import (
+ CiscoIosBase,
+ CiscoIosSSH,
+ CiscoIosTelnet,
+ CiscoIosSerial,
+)
from netmiko.cisco.cisco_ios import CiscoIosFileTransfer
+from netmiko.cisco.cisco_ios import InLineTransfer
from netmiko.cisco.cisco_asa_ssh import CiscoAsaSSH, CiscoAsaFileTransfer
+from netmiko.cisco.cisco_ftd_ssh import CiscoFtdSSH
from netmiko.cisco.cisco_nxos_ssh import CiscoNxosSSH, CiscoNxosFileTransfer
-from netmiko.cisco.cisco_xr import CiscoXrSSH, CiscoXrTelnet, CiscoCxrHa, CiscoXrFileTransfer
-from netmiko.cisco.cisco_cloudnative import CiscoCloudnativeSSH, CiscoCloudnativeTelnet
-from netmiko.cisco.cisco_bsp import CiscoBspSSH, CiscoBspTelnet
+from netmiko.cisco.cisco_xr import CiscoXrSSH, CiscoXrTelnet, CiscoXrFileTransfer
from netmiko.cisco.cisco_wlc_ssh import CiscoWlcSSH
from netmiko.cisco.cisco_s300 import CiscoS300SSH
+from netmiko.cisco.cisco_s300 import CiscoS300Telnet
from netmiko.cisco.cisco_tp_tcce import CiscoTpTcCeSSH
+from netmiko.cisco.cisco_viptela import CiscoViptelaSSH
-__all__ = ['CiscoIosSSH', 'CiscoIosTelnet', 'CiscoAsaSSH', 'CiscoNxosSSH', 'CiscoXrSSH',
- 'CiscoXrTelnet', 'CiscoWlcSSH', 'CiscoS300SSH', 'CiscoTpTcCeSSH', 'CiscoIosBase',
- 'CiscoIosFileTransfer', 'InLineTransfer', 'CiscoAsaFileTransfer',
- 'CiscoNxosFileTransfer', 'CiscoIosSerial', 'CiscoXrFileTransfer',
- 'CiscoCloudnativeSSH', 'CiscoCloudnativeTelnet','CiscoBspSSH','CiscoBspTelnet']
+__all__ = [
+ "CiscoIosSSH",
+ "CiscoIosTelnet",
+ "CiscoAsaSSH",
+ "CiscoFtdSSH",
+ "CiscoNxosSSH",
+ "CiscoXrSSH",
+ "CiscoXrTelnet",
+ "CiscoWlcSSH",
+ "CiscoS300SSH",
+ "CiscoS300Telnet",
+ "CiscoTpTcCeSSH",
+ "CiscoViptelaSSH",
+ "CiscoIosBase",
+ "CiscoIosFileTransfer",
+ "InLineTransfer",
+ "CiscoAsaFileTransfer",
+ "CiscoNxosFileTransfer",
+ "CiscoIosSerial",
+ "CiscoXrFileTransfer",
+]
diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py
index ce46bf6c2..6ed9aa15a 100644
--- a/netmiko/cisco/cisco_asa_ssh.py
+++ b/netmiko/cisco/cisco_asa_ssh.py
@@ -1,42 +1,81 @@
"""Subclass specific to Cisco ASA."""
-
-from __future__ import unicode_literals
+from typing import Any, Union, List, Dict, Optional
import re
import time
from netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer
+from netmiko.exceptions import NetmikoAuthenticationException
class CiscoAsaSSH(CiscoSSHConnection):
"""Subclass specific to Cisco ASA."""
- def session_preparation(self):
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ kwargs.setdefault("allow_auto_change", True)
+ return super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read()
+
+ # 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:
self.asa_login()
self.disable_paging(command="terminal pager 0")
- self.set_terminal_width(command="terminal width 511")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def send_command_timing(self, *args, **kwargs):
+ if self.allow_auto_change:
+ try:
+ self.send_config_set("terminal width 511")
+ except ValueError:
+ # Don't fail for the terminal width
+ pass
+ else:
+ # Disable cmd_verify if the terminal width can't be set
+ self.global_cmd_verify = False
+
+ self.set_base_prompt()
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>\#]"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = r"\#",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def send_command_timing(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
"""
If the ASA is in multi-context mode, then the base_prompt needs to be
updated after each context change.
"""
- output = super(CiscoAsaSSH, self).send_command_timing(*args, **kwargs)
+ output = super().send_command_timing(*args, **kwargs)
if len(args) >= 1:
command_string = args[0]
else:
- command_string = kwargs['command_string']
+ command_string = kwargs["command_string"]
if "changeto" in command_string:
self.set_base_prompt()
return output
- def send_command(self, *args, **kwargs):
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
"""
If the ASA is in multi-context mode, then the base_prompt needs to be
updated after each context change.
@@ -44,25 +83,21 @@ def send_command(self, *args, **kwargs):
if len(args) >= 1:
command_string = args[0]
else:
- command_string = kwargs['command_string']
+ command_string = kwargs["command_string"]
# If changeto in command, look for '#' to determine command is done
if "changeto" in command_string:
if len(args) <= 1:
- expect_string = kwargs.get('expect_string', '#')
- kwargs['expect_string'] = expect_string
- output = super(CiscoAsaSSH, self).send_command(*args, **kwargs)
+ expect_string = kwargs.get("expect_string", "#")
+ kwargs["expect_string"] = expect_string
+ output = super().send_command(*args, **kwargs)
if "changeto" in command_string:
self.set_base_prompt()
return output
- def send_command_expect(self, *args, **kwargs):
- """Backwards compaitibility."""
- return self.send_command(*args, **kwargs)
-
- def set_base_prompt(self, *args, **kwargs):
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
"""
Cisco ASA in multi-context mode needs to have the base prompt updated
(if you switch contexts i.e. 'changeto')
@@ -70,44 +105,69 @@ def set_base_prompt(self, *args, **kwargs):
This switch of ASA contexts can occur in configuration mode. If this
happens the trailing '(config*' needs stripped off.
"""
- cur_base_prompt = super(CiscoAsaSSH, self).set_base_prompt(*args, **kwargs)
- match = re.search(r'(.*)\(conf.*', cur_base_prompt)
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
+ match = re.search(r"(.*)\(conf.*", cur_base_prompt)
if match:
# strip off (conf.* from base_prompt
self.base_prompt = match.group(1)
return self.base_prompt
+ else:
+ return cur_base_prompt
- def asa_login(self):
+ def asa_login(self) -> None:
"""
Handle ASA reaching privilege level 15 using login
twb-dc-fw1> login
Username: admin
- Password: ************
+
+ Raises NetmikoAuthenticationException, if we do not reach privilege
+ level 15 after 10 loops.
"""
delay_factor = self.select_delay_factor(0)
i = 1
- max_attempts = 50
+ max_attempts = 10
self.write_channel("login" + self.RETURN)
+ output = self.read_until_pattern(pattern=r"login")
while i <= max_attempts:
- time.sleep(.5 * delay_factor)
+ time.sleep(0.5 * delay_factor)
output = self.read_channel()
- if 'sername' in output:
+ if "sername" in output:
+ assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
- elif 'ssword' in output:
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
- elif '#' in output:
- break
+ elif "#" in output:
+ return
else:
self.write_channel("login" + self.RETURN)
i += 1
- def save_config(self, cmd='write mem', confirm=False):
+ msg = "Unable to enter enable mode!"
+ raise NetmikoAuthenticationException(msg)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Saves Config"""
- return super(CiscoAsaSSH, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def normalize_linefeeds(self, a_string: str) -> str:
+ """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."""
+
pass
diff --git a/netmiko/cisco/cisco_bsp.py b/netmiko/cisco/cisco_bsp.py
deleted file mode 100644
index 608270bcf..000000000
--- a/netmiko/cisco/cisco_bsp.py
+++ /dev/null
@@ -1,289 +0,0 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-from logger.cafylog import CafyLog
-from netmiko.cisco_base_connection import CiscoBaseConnection
-from netmiko.ssh_exception import NetMikoAuthenticationException
-import re
-import time
-
-log = CafyLog()
-
-class CiscoBsp(CiscoBaseConnection):
- '''
- CiscoBsp is based of CiscoBaseConnection
- '''
- def bmc_to_bsp_prompt(self,bmc_prompt_pattern=r'\s*\#',bsp_prompt_pattern=r']\s*\#',delay_factor=1,max_loops=20):
- '''
- Switch from BMC to BSP prompt
-
- :param bmc_prompt_pattern: expected BMC prompt
- :param bsp_prompt_pattern: expected BSP prompt
- :param delay_factor: Factor to adjust delays
- :param max_loops: max number of iterations for attempting to switch prompts
- :return:
- '''
-
- self.TELNET_RETURN = '\n'
- bmc_to_bsp_cmd = "/usr/local/bin/sol.sh"
- delay_factor = self.select_delay_factor(delay_factor)
-
- i = 1
- output = self.find_prompt()
- while i <= max_loops:
- if re.search(bmc_prompt_pattern, output):
- log.debug("On BMC Prompt")
- log.debug("Sol.sh to enter BSP prompt")
- self.write_channel(bmc_to_bsp_cmd)
- time.sleep(1 * delay_factor)
- self.write_channel(self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.find_prompt()
-
- if re.search(bsp_prompt_pattern, output):
- log.debug("On BSP Prompt")
- return
-
- i += 1
-
- if not re.search(bsp_prompt_pattern, output):
- raise ValueError(f"BMC to BSP login failed. Prompt received after {max_loops} max loops is {repr(output)}")
-
- def bsp_to_bmc_prompt(self,bmc_prompt_pattern=r'\s*\#',bsp_prompt_pattern=r']\s*\#',delay_factor=1, max_loops=20):
- '''
- Switch from BSP to BMC prompt
-
- :param bmc_prompt_pattern: expected BMC prompt
- :param bsp_prompt_pattern: expected BSP prompt
- :param delay_factor: Factor to adjust delays
- :param max_loops: max number of iterations for attempting to switch prompts
- :return:
- '''
-
- self.TELNET_RETURN = '\n'
- CTRL_L = "\x0c"
- delay_factor = self.select_delay_factor(delay_factor)
-
- i = 1
- output = self.find_prompt()
- while i <= max_loops:
- if re.search(bsp_prompt_pattern, output):
- log.debug("On BSP Prompt")
- log.debug("Ctrl + L; press X to enter BMC prompt")
- self.write_channel(CTRL_L)
- time.sleep(1 * delay_factor)
- self.write_channel('x'+self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.find_prompt()
-
- if re.search(bmc_prompt_pattern, output):
- log.debug("On BMC Prompt")
- return
-
- i += 1
-
- if not re.search(bmc_prompt_pattern, output):
- raise ValueError(f"BSP to BMC login failed. Prompt received after {max_loops} max loops is {repr(output)}")
-
- def bmc_login(self,prompt_pattern=r'\s*\#',username_pattern='login',pwd_pattern=r'assword',delay_factor=1, max_loops=20):
- '''
- Handle BMC login prompt
-
- :param prompt_pattern: expected BMC prompt
- :param username_pattern: username prompt pattern
- :param pwd_pattern: password prompt pattern
- :param delay_factor: Factor to adjust delays
- :param max_loops: max number of iterations for attempting to login to BMC prompt before raising exception
- :return:
- '''
-
- bmc_username = "root"
- bmc_pass = "0penBmc"
- self.TELNET_RETURN = '\n'
-
- i = 1
- while i <= max_loops:
- i += 1
- output = self.find_prompt()
-
- log.debug("Check if we are already on BMC prompt")
- if re.search(prompt_pattern, output):
- log.debug("On BMC Prompt")
- return
-
- log.debug("Check if BMC Username Prompt detected")
- if re.search(username_pattern, output):
- log.debug(f"BMC Username pattern detected, sending Username={bmc_username}")
- time.sleep(1)
- self.write_channel(bmc_username)
- time.sleep(1 * delay_factor)
- output = self.find_prompt()
-
- log.debug("Check if BMC Password Prompt detected")
- if re.search(pwd_pattern, output):
- log.debug(f"BMC Password pattern detected, sending Password={bmc_pass}")
- self.write_channel(bmc_pass)
- time.sleep(.5 * delay_factor)
- output = self.find_prompt()
-
- if re.search(prompt_pattern, output):
- log.debug("On BMC Prompt")
- return
-
- if re.search(pwd_pattern, output):
- self.write_channel(bmc_pass)
- time.sleep(.5 * delay_factor)
-
- # Last try to see if we already logged in
- self.write_channel(self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.find_prompt()
- if re.search(prompt_pattern, output):
- log.debug("On BMC Prompt")
- return
-
- raise NetMikoAuthenticationException("LAST_TRY login failed for BMC Prompt")
-
- def set_base_prompt(self, pri_prompt_terminator='#',alt_prompt_terminator='$', delay_factor=1):
- """Sets self.base_prompt
-
- Used as delimiter for stripping of trailing prompt in output.
-
- Should be set to something that is general and applies in multiple contexts. For Cisco
- devices this will be set to router hostname (i.e. prompt without '>' or '#').
-
- This will be set on entering user exec or privileged exec on Cisco, but not when
- entering/exiting config mode.
-
- :param pri_prompt_terminator: Primary trailing delimiter for identifying a device prompt
- :type pri_prompt_terminator: str
-
- :param alt_prompt_terminator: Alternate trailing delimiter for identifying a device prompt
- :type alt_prompt_terminator: str
-
- :param delay_factor: See __init__: global_delay_factor
- :type delay_factor: int
- """
- prompt = self.find_prompt(delay_factor=delay_factor)
- if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator) and 'bmc' not in prompt:
- raise ValueError(f"BSP prompt not found: {repr(prompt)}")
- # Strip off trailing terminator
- self.base_prompt = prompt[:-1]
- return self.base_prompt
-
- def disable_paging(self, *args, **kwargs):
- """Paging is disabled by default."""
- return ""
-
-class CiscoBspSSH(CiscoBsp):
- '''
- CiscoBspSSH is based of CiscoBsp -- CiscoBaseConnection
- '''
-
- pass
-
-class CiscoBspTelnet(CiscoBsp):
- '''
- CiscoBspTelnet is based of CiscoBsp -- CiscoBaseConnection
- '''
-
- def telnet_login(self,pri_prompt_terminator=r']\s*\#',alt_prompt_terminator=r']\s*\$',username_pattern=r'login',pwd_pattern=r'assword',delay_factor=1,max_loops=20):
- '''
- Telnet login to BSP prompt
-
- :param pri_prompt_terminator: primary prompt pattern (for root user)
- :param alt_prompt_terminator: alternate prompt pattern (for non-root user eg: cisco user)
- :param username_pattern: username prompt pattern
- :param pwd_pattern: password prompt pattern
- :param delay_factor: Factor to adjust delays
- :param max_loops: max number of iterations for attempting to login to BSP prompt before raising exception
- :return:
- '''
-
- self.TELNET_RETURN = '\n'
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(1 * delay_factor)
- my_username = self.username
- my_password = self.password
- return_msg = ''
- i = 1
- while i <= max_loops:
- try:
- # self.read_channel which internally calls telnetlib.read_ver_eager() returns empty string
- log.debug("Reading channel for the first time")
- output = self.read_channel()
-
- # self.find_prompt will return prompt after logging in
- log.debug(f"Output after reading channel for first time: {output}")
- if output == '':
- time.sleep(2 * delay_factor)
- log.debug("output is empty, doing find_prompt()")
- output = self.find_prompt()
- log.debug(f"Output after doing find_prompt: {output}")
- return_msg += output
-
- log.debug("Checking if Password Prompt")
- if re.search(pwd_pattern, output):
- log.debug("Differentiate whether it is password prompt for BMC or BSP")
- self.write_channel(self.TELNET_RETURN)
- output = self.find_prompt()
- return_msg += output
-
- log.debug("Checking if BMC prompt")
- if 'bmc' in output:
- log.debug("BMC Login prompt detected")
- self.bmc_login()
- time.sleep(2 * delay_factor)
- self.bmc_to_bsp_prompt()
- time.sleep(2 * delay_factor)
- output = self.find_prompt()
- return_msg += output
-
- log.debug("Searching for username pattern")
- if re.search(username_pattern, output):
- log.debug(f"Username pattern detected, sending Username={my_username}")
- time.sleep(1)
- self.write_channel(my_username + self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
- log.debug(f"After sending username, the output pattern is={output}")
-
- log.debug("Searching for password pattern")
- if re.search(pwd_pattern, output):
- self.write_channel(my_password + self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
- if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(alt_prompt_terminator, output,flags=re.M):
- return return_msg
-
- if re.search(pwd_pattern, output):
- self.write_channel(my_password + self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
- # Check for device with no password configured
- if re.search(r"assword required, but none set", output):
- raise NetMikoAuthenticationException(f"Telnet login failed - Password required, but none set: {self.host}")
-
- # Check if already on BSP prompt
- if re.findall(pri_prompt_terminator, output) or re.findall(alt_prompt_terminator, output):
- return return_msg
-
- self.write_channel(self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- i += 1
- except EOFError:
- raise NetMikoAuthenticationException(f"EOFError Telnet login failed: {self.host}")
-
- # Last try to see if we already logged in
- self.write_channel(self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.read_channel()
- return_msg += output
- if (re.search(pri_prompt_terminator, output, flags=re.M) or re.search(alt_prompt_terminator, output,flags=re.M)):
- return return_msg
-
- raise NetMikoAuthenticationException(f"LAST_TRY Telnet login failed: {self.host}")
diff --git a/netmiko/cisco/cisco_cloudnative.py b/netmiko/cisco/cisco_cloudnative.py
deleted file mode 100644
index 6f53567de..000000000
--- a/netmiko/cisco/cisco_cloudnative.py
+++ /dev/null
@@ -1,285 +0,0 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import re
-import time
-import logging
-
-from netmiko.cisco_base_connection import CiscoBaseConnection
-
-class CiscoCloudnative(CiscoBaseConnection):
-
- def session_preparation(self):
- """Prepare the session after the connection has been established.
- When router in 'run' (linux $) prompt, switch back to XR prompt
- """
-
- username_pattern=r"(sername)|(ogin)"
- pwd_pattern=r"assword"
- self.set_base_prompt(alt_prompt_terminator='$')
- switch_to_xr_command = 'xr'
- if self.find_prompt().endswith('$'):
- if self._check_for_thinxr_host_prompt() == False:
- self.send_command(switch_to_xr_command, expect_string='#')
- self.base_prompt = self.find_prompt()
- #The below block is added to address getting username/login prompt When
- #the box is reloaded
- elif username_pattern in self.find_prompt():
- elf.send_command(self.username, expect_string=pwd_pattern)
- #time.sleep(1 * delay_factor)
- self.send_command(self.password, expect_string='#')
- #time.sleep(.5 * delay_factor)
- self.base_prompt = self.find_prompt()
- if pri_prompt_terminator in self.base_prompt:
- raise ValueError("Could not go to $prompt")
-
- self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
-
- def _check_for_thinxr_host_prompt(self, pri_prompt_terminator='#',
- username_pattern=r"(sername)|(ogin)", pwd_pattern=r"assword",
- delay_factor=1, max_loops=60):
- SSH_RETURN = '\r\n'
- linux_prompt_pattern = "[xr:~]$"
- switch_to_xr_command = 'xr'
- output = ''
- return_msg = ''
- if self.find_prompt() == linux_prompt_pattern:
- self.write_channel(SSH_RETURN + "xr" + SSH_RETURN)
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
- # Search for username pattern / send username and then expect Password
- #pattern and send password and expect xr prompt'#'
- if re.search(username_pattern, output):
- self.send_command(self.username, expect_string=pwd_pattern)
- #time.sleep(1 * delay_factor)
- self.send_command(self.password, expect_string='#')
- #time.sleep(.5 * delay_factor)
- self.base_prompt = self.find_prompt()
- if pri_prompt_terminator in self.base_prompt:
- return True
- else:
- return False
-
-
- def config_mode(self, config_command='config terminal', pattern='', skip_check=True):
- """
- Enter into configuration mode on remote device.
-
- Cisco IOSXR devices abbreviate the prompt at 20 chars in config mode
- """
- if not pattern:
- #pattern = self.base_prompt[:16]
- #pattern = self.current_prompt[:16]
- pattern = self.base_prompt[:16]
- #pattern = self.current_prompt[:16]
- pattern = pattern + ".*config"
- return super(CiscoBaseConnection, self).config_mode(config_command=config_command,
- pattern=pattern)
-
- def send_config_set(self, config_commands=None, exit_config_mode=True, **kwargs):
- """IOS-XR requires you not exit from configuration mode."""
- '''
- return super(CiscoCloudnative, self).send_config_set(config_commands=config_commands,
- exit_config_mode=False, **kwargs)
- '''
- return super(CiscoCloudnative, self).send_config_set(config_commands=config_commands,\
- exit_config_mode=False, **kwargs)
-
- def commit(self, confirm=False, confirm_delay=None, comment='', label='',
- replace=False,best_effort = False, force= False,
- delay_factor=1,
- max_timeout=30, **kwargs):
- """
- Commit the candidate configuration.
-
- default (no options):
- command_string = commit
- confirm and confirm_delay:
- command_string = commit confirmed
- label (which is a label name):
- command_string = commit label
- comment:
- command_string = commit comment
-
- supported combinations
- label and confirm:
- command_string = commit label confirmed
- label and comment:
- command_string = commit label comment
-
- All other combinations will result in an exception.
-
- failed commit message:
- % Failed to commit one or more configuration items during a pseudo-atomic operation. All
- changes made have been reverted. Please issue 'show configuration failed [inheritance]'
- from this session to view the errors
-
- message XR shows if other commits occurred:
- One or more commits have occurred from other configuration sessions since this session
- started or since the last commit was made from this session. You can use the 'show
- configuration commit changes' command to browse the changes.
-
- Exit of configuration mode with pending changes will cause the changes to be discarded and
- an exception to be generated.
- """
- commit_error_dialog_dict = kwargs.get('commit_error_dialog_dict')
- if 'commit_error_dialog_dict' in kwargs:
- kwargs.pop('commit_error_dialog_dict')
- delay_factor = self.select_delay_factor(delay_factor)
- if confirm and not confirm_delay:
- raise ValueError("Invalid arguments supplied to XR commit")
- if confirm_delay and not confirm:
- raise ValueError("Invalid arguments supplied to XR commit")
- if comment and confirm:
- raise ValueError("Invalid arguments supplied to XR commit")
-
- # wrap the comment in quotes
- # wrap the comment in quotes
- if comment:
- if '"' in comment:
- raise ValueError("Invalid comment contains double quote")
- comment = '"{0}"'.format(comment)
-
- label = str(label)
- error_marker = 'Failed to'
- alt_error_marker = 'One or more commits have occurred from other'
-
- # Select proper command string based on arguments provided
- if label:
- if comment:
- command_string = 'commit label {0} comment {1}'.format(label, comment)
- elif confirm:
- command_string = 'commit label {0} confirmed {1}'.format(label, str(confirm_delay))
- else:
- command_string = 'commit label {0}'.format(label)
- elif confirm:
- command_string = 'commit confirmed {0}'.format(str(confirm_delay))
- elif comment:
- command_string = 'commit comment {0}'.format(comment)
- else:
- command_string = 'commit'
-
- # Enter config mode (if necessary)
- #output = self.config_mode()
- output = ''
- if replace:
- output += self.send_command_timing('commit replace', strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- commit_replace_marker = "This commit will replace or remove the entire running configuration"
- if commit_replace_marker in output:
- output += self.send_command_timing("yes", strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- return output
-
- else:
- try:
- output += self.send_command_expect(command_string, strip_prompt=False, strip_command=False,
- delay_factor=delay_factor, **kwargs)
- if error_marker in output:
- raise ValueError("Commit failed with the following errors:\n\n{0}".format(output))
- else:
- return output
- except Exception as err:
- output = str(err)
- if commit_error_dialog_dict is not None and alt_error_marker in commit_error_dialog_dict:
- if alt_error_marker in output:
- marker_value = commit_error_dialog_dict[alt_error_marker]
- output += self.send_command_timing(marker_value, strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- return output
- elif alt_error_marker in output:
- # Other commits occurred, don't proceed with commit
- output += self.send_command_timing("no", strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- raise ValueError("Commit failed with the following errors:\n\n{0}".format(output))
- else:
- raise err
-
-
- def check_config_mode(self, check_string=')#', pattern=r"[#\$]"):
- """Checks if the device is in configuration mode or not.
-
- IOS-cXR, unfortunately, does this:
- RP/0/RSP0/CPU0:BNG(admin)#
- """
- self.write_channel('\n')
- output = self.read_until_pattern(pattern=pattern)
- # Strip out (admin) so we don't get a false positive with (admin)#
- # (admin-config)# would still match.
- output = output.replace("(admin)", "")
- return check_string in output
-
-
- def exit_config_mode(self, exit_config='end', skip_check=False):
- """Exit configuration mode."""
- output = ''
-
- if skip_check or self.check_config_mode():
- output = self.send_command_timing(exit_config, strip_prompt=False,
- strip_command=False)
- if "Uncommitted changes found" in output:
- output += self.send_command_timing('no\n', strip_prompt=False, strip_command=False)
-
- if skip_check:
- return output
- if self.check_config_mode():
- raise ValueError("Failed to exit configuration mode")
- return output
-
- @staticmethod
- def normalize_linefeeds(a_string):
- """Convert '\r\n','\r\r\n', '\n\r', or '\r' to '\n."""
- newline = re.compile(r'(\r\r\n|\r\n|\n\r|\r)')
- return newline.sub('\n', a_string)
-
-class CiscoCloudnativeSSH(CiscoCloudnative):
- '''
- CiscoCloudnativeSSH is based of CiscoCloudnative -- CiscoBaseConnection
- '''
- pass
-
-class CiscoCloudnativeTelnet(CiscoCloudnative):
- '''
- CiscoCloudnativeTelnet is based of CiscoCloudnative -- CiscoBaseConnection
- '''
- def session_preparation(self):
- """Prepare the session after the connection has been established."""
- self.set_base_prompt()
-
- if 'RP Node is not ' in self.find_prompt():
- # Incase of standby - skip rest of section
- return
- self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
-
- def set_base_prompt(self, pri_prompt_terminator='#',
- alt_prompt_terminator='>', delay_factor=1,
- standby_prompt='RP Node is not ',
- ):
- """
- Sets self.base_prompt
-
- Used as delimiter for stripping of trailing prompt in output.
-
- Should be set to something that is general and applies in multiple contexts. For Cisco
- devices this will be set to router hostname (i.e. prompt without '>' or '#').
-
- This will be set on entering user exec or privileged exec on Cisco, but not when
- entering/exiting config mode.
- """
- prompt = self.find_prompt(delay_factor=delay_factor)
- list_of_valid_prompts = []
- list_of_valid_prompts.append(pri_prompt_terminator)
- list_of_valid_prompts.append(alt_prompt_terminator)
- if standby_prompt in prompt:
- self.base_prompt = prompt
- return self.base_prompt
- if not prompt[-1] in list_of_valid_prompts:
- raise ValueError("Router prompt not found: {0}".format(prompt))
- # Strip off trailing terminator
- self.base_prompt = prompt[:-1]
- return self.base_prompt
diff --git a/netmiko/cisco/cisco_ftd_ssh.py b/netmiko/cisco/cisco_ftd_ssh.py
new file mode 100644
index 000000000..939e9dbc8
--- /dev/null
+++ b/netmiko/cisco/cisco_ftd_ssh.py
@@ -0,0 +1,22 @@
+"""Subclass specific to Cisco FTD."""
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoFtdSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ """Subclass specific to Cisco FTD."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+
+ def send_config_set(self, *args: Any, **kwargs: Any) -> str:
+ """Canot change config on FTD via ssh"""
+ raise NotImplementedError
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Canot change config on FTD via ssh"""
+ return False
diff --git a/netmiko/cisco/cisco_ios.py b/netmiko/cisco/cisco_ios.py
index 34d30c615..d9f50722d 100644
--- a/netmiko/cisco/cisco_ios.py
+++ b/netmiko/cisco/cisco_ios.py
@@ -1,5 +1,5 @@
-from __future__ import unicode_literals
-
+from typing import Any, Optional, Callable, Type
+from types import TracebackType
import time
import re
import os
@@ -7,66 +7,108 @@
import io
from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
+from netmiko.base_connection import BaseConnection
class CiscoIosBase(CiscoBaseConnection):
"""Common Methods for IOS (both SSH and telnet)."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r'[>#]')
- self.set_base_prompt()
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.set_base_prompt()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = r"#") -> bool:
+ """
+ Checks if the device is in configuration mode or not.
- def save_config(self, cmd='write mem', confirm=False):
+ Cisco IOS devices abbreviate the prompt at 20 chars in config mode
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Saves Config Using Copy Run Start"""
- return super(CiscoIosBase, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
class CiscoIosSSH(CiscoIosBase):
"""Cisco IOS SSH driver."""
+
pass
class CiscoIosTelnet(CiscoIosBase):
"""Cisco IOS Telnet driver."""
+
pass
class CiscoIosSerial(CiscoIosBase):
"""Cisco IOS Serial driver."""
+
pass
class CiscoIosFileTransfer(CiscoFileTransfer):
"""Cisco IOS SCP File Transfer driver."""
+
pass
class InLineTransfer(CiscoIosFileTransfer):
"""Use TCL on Cisco IOS to directly transfer file."""
- def __init__(self, ssh_conn, source_file=None, dest_file=None, file_system=None,
- direction='put', source_config=None):
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str = "",
+ dest_file: str = "",
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ source_config: Optional[str] = None,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
+
+ if not dest_file:
+ raise ValueError(
+ "Destination file must be specified for InlineTransfer operations."
+ )
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for InLineTransfer")
+
if source_file and source_config:
msg = "Invalid call to InLineTransfer both source_file and source_config specified."
raise ValueError(msg)
- if direction != 'put':
+ if direction != "put":
raise ValueError("Only put operation supported by InLineTransfer.")
+ if progress is not None or progress4 is not None:
+ raise NotImplementedError(
+ "Progress bar is not supported on inline transfers."
+ )
+ else:
+ self.progress = progress
+ self.progress4 = progress4
+
self.ssh_ctl_chan = ssh_conn
+ self.source_file = source_file
if source_file:
- self.source_file = source_file
self.source_config = None
self.source_md5 = self.file_md5(source_file)
self.file_size = os.stat(source_file).st_size
elif source_config:
- self.source_file = None
self.source_config = source_config
self.source_md5 = self.config_md5(source_config)
- self.file_size = len(source_config.encode('UTF-8'))
+ self.file_size = len(source_config.encode("UTF-8"))
self.dest_file = dest_file
self.direction = direction
@@ -75,14 +117,16 @@ def __init__(self, ssh_conn, source_file=None, dest_file=None, file_system=None,
else:
self.file_system = file_system
+ self.socket_timeout = socket_timeout
+
@staticmethod
- def _read_file(file_name):
- with io.open(file_name, "rt", encoding='utf-8') as f:
+ def _read_file(file_name: str) -> str:
+ with io.open(file_name, "rt", encoding="utf-8") as f:
return f.read()
@staticmethod
- def _tcl_newline_rationalize(tcl_string):
- """
+ def _tcl_newline_rationalize(tcl_string: str) -> str:
+ r"""
When using put inside a TCL {} section the newline is considered a new TCL
statement and causes a missing curly-brace message. Convert "\n" to "\r". TCL
will convert the "\r" to a "\n" i.e. you will see a "\n" inside the file on the
@@ -96,61 +140,75 @@ def _tcl_newline_rationalize(tcl_string):
raise ValueError(msg)
return tmp_string
- def __enter__(self):
+ def __enter__(self) -> "InLineTransfer":
self._enter_tcl_mode()
return self
- def __exit__(self, exc_type, exc_value, traceback):
- _ = self._exit_tcl_mode() # noqa
-
- def _enter_tcl_mode(self):
- TCL_ENTER = 'tclsh'
- cmd_failed = ['Translating "tclsh"', '% Unknown command', '% Bad IP address']
- output = self.ssh_ctl_chan.send_command(TCL_ENTER, expect_string=r"\(tcl\)#",
- strip_prompt=False, strip_command=False)
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
+ self._exit_tcl_mode()
+
+ def _enter_tcl_mode(self) -> str:
+ TCL_ENTER = "tclsh"
+ cmd_failed = ['Translating "tclsh"', "% Unknown command", "% Bad IP address"]
+ output = self.ssh_ctl_chan._send_command_str(
+ TCL_ENTER,
+ expect_string=r"\(tcl\)#",
+ strip_prompt=False,
+ strip_command=False,
+ )
for pattern in cmd_failed:
if pattern in output:
- raise ValueError("Failed to enter tclsh mode on router: {}".format(output))
+ raise ValueError(f"Failed to enter tclsh mode on router: {output}")
return output
- def _exit_tcl_mode(self):
- TCL_EXIT = 'tclquit'
+ def _exit_tcl_mode(self) -> str:
+ TCL_EXIT = "tclquit"
self.ssh_ctl_chan.write_channel("\r")
time.sleep(1)
output = self.ssh_ctl_chan.read_channel()
- if '(tcl)' in output:
+ if "(tcl)" in output:
self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
time.sleep(1)
output += self.ssh_ctl_chan.read_channel()
return output
- def establish_scp_conn(self):
+ def establish_scp_conn(self) -> None:
raise NotImplementedError
- def close_scp_chan(self):
+ def close_scp_chan(self) -> None:
raise NotImplementedError
- def local_space_available(self):
+ def local_space_available(self) -> bool:
raise NotImplementedError
- def file_md5(self, file_name):
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
"""Compute MD5 hash of file."""
+ if add_newline is True:
+ raise ValueError(
+ "add_newline argument is not supported for inline transfers."
+ )
file_contents = self._read_file(file_name)
- file_contents = file_contents + '\n' # Cisco IOS automatically adds this
- file_contents = file_contents.encode('UTF-8')
- return hashlib.md5(file_contents).hexdigest()
-
- def config_md5(self, source_config):
- """Compute MD5 hash of file."""
- file_contents = source_config + '\n' # Cisco IOS automatically adds this
- file_contents = file_contents.encode('UTF-8')
- return hashlib.md5(file_contents).hexdigest()
-
- def put_file(self):
- curlybrace = r'{'
- TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(self.file_system,
- self.dest_file, curlybrace)
- TCL_FILECMD_EXIT = '}'
+ file_contents = file_contents + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def config_md5(self, source_config: str) -> str:
+ """Compute MD5 hash of text."""
+ file_contents = source_config + "\n" # Cisco IOS automatically adds this
+ file_contents_bytes = file_contents.encode("UTF-8")
+ return hashlib.md5(file_contents_bytes).hexdigest()
+
+ def put_file(self) -> None:
+ curlybrace = r"{"
+ TCL_FILECMD_ENTER = 'puts [open "{}{}" w+] {}'.format(
+ self.file_system, self.dest_file, curlybrace
+ )
+ TCL_FILECMD_EXIT = "}"
if self.source_file:
file_contents = self._read_file(self.source_file)
@@ -162,40 +220,46 @@ def put_file(self):
self.ssh_ctl_chan.clear_buffer()
self.ssh_ctl_chan.write_channel(TCL_FILECMD_ENTER)
- time.sleep(.25)
+ time.sleep(0.25)
self.ssh_ctl_chan.write_channel(file_contents)
self.ssh_ctl_chan.write_channel(TCL_FILECMD_EXIT + "\r")
# This operation can be slow (depends on the size of the file)
- max_loops = 400
+ read_timeout = 100
sleep_time = 4
if self.file_size >= 2500:
- max_loops = 1500
+ read_timeout = 300
sleep_time = 12
elif self.file_size >= 7500:
- max_loops = 3000
+ read_timeout = 600
sleep_time = 25
# Initial delay
time.sleep(sleep_time)
# File paste and TCL_FILECMD_exit should be indicated by "router(tcl)#"
- output = self.ssh_ctl_chan._read_channel_expect(pattern=r"\(tcl\)", max_loops=max_loops)
+ output = self.ssh_ctl_chan.read_until_pattern(
+ pattern=r"\(tcl\).*$", re_flags=re.M, read_timeout=read_timeout
+ )
# The file doesn't write until tclquit
- TCL_EXIT = 'tclquit'
+ TCL_EXIT = "tclquit"
self.ssh_ctl_chan.write_channel(TCL_EXIT + "\r")
time.sleep(1)
# Read all data remaining from the TCLSH session
- output += self.ssh_ctl_chan._read_channel_expect(max_loops=max_loops)
- return output
-
- def get_file(self):
+ pattern = rf"tclquit.*{self.ssh_ctl_chan.base_prompt}.*$"
+ re_flags = re.DOTALL | re.M
+ output += self.ssh_ctl_chan.read_until_pattern(
+ pattern=pattern, re_flags=re_flags, read_timeout=read_timeout
+ )
+ return None
+
+ def get_file(self) -> None:
raise NotImplementedError
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
diff --git a/netmiko/cisco/cisco_nxos_ssh.py b/netmiko/cisco/cisco_nxos_ssh.py
index 6b820177a..d41bfffc6 100644
--- a/netmiko/cisco/cisco_nxos_ssh.py
+++ b/netmiko/cisco/cisco_nxos_ssh.py
@@ -1,80 +1,143 @@
-from __future__ import print_function
-from __future__ import unicode_literals
+from typing import Any, Optional, Callable
import re
-import time
import os
+from netmiko.base_connection import BaseConnection
from netmiko.cisco_base_connection import CiscoSSHConnection
from netmiko.cisco_base_connection import CiscoFileTransfer
class CiscoNxosSSH(CiscoSSHConnection):
-
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r'[>#]')
self.ansi_escape_codes = True
- self.set_base_prompt()
+ # NX-OS has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_terminal_width(
+ command="terminal width 511", pattern=r"terminal width 511"
+ )
self.disable_paging()
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ self.set_base_prompt()
- def normalize_linefeeds(self, a_string):
+ def normalize_linefeeds(self, a_string: str) -> str:
"""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)')
- return newline.sub(self.RESPONSE_RETURN, a_string).replace('\r', '')
+ 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")
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """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: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ # NX-OS is very slow on save_config ensure it waits long enough.
+ output += self._send_command_str(
+ command_string=cmd,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=100,
+ )
+ return output
class CiscoNxosFileTransfer(CiscoFileTransfer):
"""Cisco NXOS SCP File Transfer driver."""
- def __init__(self, ssh_conn, source_file, dest_file, file_system='bootflash:', direction='put'):
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: str = "bootflash:",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
self.ssh_ctl_chan = ssh_conn
self.source_file = source_file
self.dest_file = dest_file
self.direction = direction
+ if hash_supported is False:
+ raise ValueError("hash_supported=False is not supported for NX-OS")
+
if file_system:
self.file_system = file_system
else:
raise ValueError("Destination file system must be specified for NX-OS")
- if direction == 'put':
+ if direction == "put":
self.source_md5 = self.file_md5(source_file)
self.file_size = os.stat(source_file).st_size
- elif direction == 'get':
+ elif direction == "get":
self.source_md5 = self.remote_md5(remote_file=source_file)
self.file_size = self.remote_file_size(remote_file=source_file)
else:
raise ValueError("Invalid direction specified")
- def check_file_exists(self, remote_cmd=""):
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
- if self.direction == 'put':
+ if self.direction == "put":
if not remote_cmd:
- remote_cmd = "dir {}{}".format(self.file_system, self.dest_file)
- remote_out = self.ssh_ctl_chan.send_command_expect(remote_cmd)
+ remote_cmd = f"dir {self.file_system}{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
search_string = r"{}.*Usage for".format(self.dest_file)
- if 'No such file or directory' in remote_out:
+ if "No such file or directory" in remote_out:
return False
elif re.search(search_string, remote_out, flags=re.DOTALL):
return True
else:
raise ValueError("Unexpected output from check_file_exists")
- elif self.direction == 'get':
+ elif self.direction == "get":
return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
- def remote_file_size(self, remote_cmd="", remote_file=None):
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""Get the file size of the remote file."""
if remote_file is None:
- if self.direction == 'put':
+ if self.direction == "put":
remote_file = self.dest_file
- elif self.direction == 'get':
+ elif self.direction == "get":
remote_file = self.source_file
+ else:
+ raise ValueError("Invalid value for file transfer direction.")
if not remote_cmd:
- remote_cmd = "dir {}/{}".format(self.file_system, remote_file)
+ remote_cmd = f"dir {self.file_system}/{remote_file}"
- remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if re.search("no such file or directory", remote_out, flags=re.I):
+ raise IOError("Unable to find file on remote system")
# Match line containing file name
escape_file_name = re.escape(remote_file)
pattern = r".*({}).*".format(escape_file_name)
@@ -82,28 +145,30 @@ def remote_file_size(self, remote_cmd="", remote_file=None):
if match:
file_size = match.group(0)
file_size = file_size.split()[0]
-
- if 'No such file or directory' in remote_out:
- raise IOError("Unable to find file on remote system")
- else:
return int(file_size)
+ raise IOError("Unable to find file on remote system")
+
@staticmethod
- def process_md5(md5_output, pattern=r"= (.*)"):
+ def process_md5(md5_output: str, pattern: str = r"= (.*)") -> str:
"""Not needed on NX-OS."""
raise NotImplementedError
- def remote_md5(self, base_cmd='show file', remote_file=None):
+ def remote_md5(
+ self, base_cmd: str = "show file", remote_file: Optional[str] = None
+ ) -> str:
if remote_file is None:
- if self.direction == 'put':
+ if self.direction == "put":
remote_file = self.dest_file
- elif self.direction == 'get':
+ elif self.direction == "get":
remote_file = self.source_file
- remote_md5_cmd = "{} {}{} md5sum".format(base_cmd, self.file_system, remote_file)
- return self.ssh_ctl_chan.send_command(remote_md5_cmd, max_loops=1500)
+ remote_md5_cmd = f"{base_cmd} {self.file_system}{remote_file} md5sum"
+ output = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ output = output.strip()
+ return output
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
diff --git a/netmiko/cisco/cisco_s300.py b/netmiko/cisco/cisco_s300.py
index ee95f8af1..1058c4a3b 100644
--- a/netmiko/cisco/cisco_s300.py
+++ b/netmiko/cisco/cisco_s300.py
@@ -1,9 +1,7 @@
-from __future__ import unicode_literals
-import time
from netmiko.cisco_base_connection import CiscoSSHConnection
-class CiscoS300SSH(CiscoSSHConnection):
+class CiscoS300Base(CiscoSSHConnection):
"""
Support for Cisco SG300 series of devices.
@@ -12,16 +10,34 @@ class CiscoS300SSH(CiscoSSHConnection):
configure terminal
ip ssh password-auth
"""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self.ansi_escape_codes = True
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
self.disable_paging(command="terminal datadump")
- self.set_terminal_width(command='terminal width 511')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- def save_config(self, cmd='write memory', confirm=True, confirm_response='Y'):
- return super(CiscoS300SSH, self).save_config(cmd=cmd, confirm=confirm,
- confirm_response=confirm_response)
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = True,
+ confirm_response: str = "Y",
+ ) -> str:
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class CiscoS300SSH(CiscoS300Base):
+ pass
+
+
+class CiscoS300Telnet(CiscoS300Base):
+ """
+ Support for Cisco SG300 series of devices, with telnet.
+ Note: can be used with Sx200 series, with telnet enabled.
+ """
+
+ pass
diff --git a/netmiko/cisco/cisco_tp_tcce.py b/netmiko/cisco/cisco_tp_tcce.py
index e779dac50..5e37e5851 100644
--- a/netmiko/cisco/cisco_tp_tcce.py
+++ b/netmiko/cisco/cisco_tp_tcce.py
@@ -4,24 +4,25 @@
Expressway/VCS
Written by Ahmad Barrin
+Updated by Kirk Byers
"""
-from __future__ import unicode_literals
+from typing import Any, Union, List, Dict
import time
import re
from netmiko.cisco_base_connection import CiscoSSHConnection
class CiscoTpTcCeSSH(CiscoSSHConnection):
- 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(CiscoTpTcCeSSH, self).__init__(*args, **kwargs)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
- def disable_paging(self, *args, **kwargs):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
"""Paging is disabled by default."""
return ""
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""
Prepare the session after the connection has been established
@@ -33,26 +34,28 @@ def session_preparation(self):
self.disable_paging()
self.set_terminal_width()
"""
+ # Could not work out what the CLI looked like. It would be good to switch to
+ # a pattern on the _test_channel_read() call.
self._test_channel_read()
self.set_base_prompt()
- self.disable_paging()
self.set_terminal_width()
+ self.disable_paging()
# Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
+ time.sleep(0.3 * self.global_delay_factor)
self.clear_buffer()
- def set_base_prompt(self, *args, **kwargs):
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
"""Use 'OK' as base_prompt."""
- self.base_prompt = 'OK'
+ self.base_prompt = "OK"
return self.base_prompt
- def find_prompt(self, *args, **kwargs):
+ def find_prompt(self, *args: Any, **kwargs: Any) -> str:
"""Use 'OK' as standard prompt."""
- return 'OK'
+ return "OK"
- def strip_prompt(self, a_string):
+ def strip_prompt(self, a_string: str) -> str:
"""Strip the trailing router prompt from the output."""
- expect_string = r'^(OK|ERROR|Command not recognized\.)$'
+ expect_string = r"^(OK|ERROR|Command not recognized\.)$"
response_list = a_string.split(self.RESPONSE_RETURN)
last_line = response_list[-1]
if re.search(expect_string, last_line):
@@ -60,32 +63,27 @@ def strip_prompt(self, a_string):
else:
return a_string
- def send_command(self, *args, **kwargs):
- '''
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """
Send command to network device retrieve output until router_prompt or expect_string
By default this method will keep waiting to receive data until the network device prompt is
detected. The current network device prompt will be determined automatically.
-
- command_string = command to execute
- expect_string = pattern to search for uses re.search (use raw strings)
- delay_factor = decrease the initial delay before we start looking for data
- max_loops = number of iterations before we give up and raise an exception
- strip_prompt = strip the trailing prompt from the output
- strip_command = strip the leading command from the output
- '''
+ """
if len(args) >= 2:
expect_string = args[1]
else:
- expect_string = kwargs.get('expect_string')
+ expect_string = kwargs.get("expect_string")
if expect_string is None:
- expect_string = r'(OK|ERROR|Command not recognized\.)'
+ expect_string = r"(OK|ERROR|Command not recognized\.)"
expect_string = self.RETURN + expect_string + self.RETURN
- kwargs.setdefault('expect_string', expect_string)
+ kwargs.setdefault("expect_string", expect_string)
- output = super(CiscoSSHConnection, self).send_command(*args, **kwargs)
+ output = super().send_command(*args, **kwargs)
return output
- def save_config(self):
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/cisco/cisco_viptela.py b/netmiko/cisco/cisco_viptela.py
new file mode 100644
index 000000000..a06dcd35e
--- /dev/null
+++ b/netmiko/cisco/cisco_viptela.py
@@ -0,0 +1,80 @@
+"""Subclass specific to Cisco Viptela."""
+from typing import Union, Sequence, TextIO, Any
+import re
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoViptelaSSH(CiscoSSHConnection):
+ """Subclass specific to Cisco Viptela."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="paginate false")
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """Checks if the device is in configuration mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def commit(self, confirm: bool = False, confirm_response: str = "") -> str:
+ cmd = "commit"
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def config_mode(
+ self,
+ config_command: str = "conf terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#") -> str:
+ """
+ Exit from configuration mode.
+
+ Viptela might have the following in the output (if no 'commit()' occurred.
+
+ Uncommitted changes found, commit them? [yes/no/CANCEL]
+ """
+ output = ""
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_config.strip())
+ )
+ if not re.search(pattern, output, flags=re.M):
+ uncommit_pattern = r"Uncommitted changes found"
+ new_pattern = f"({pattern}|{uncommit_pattern})"
+ output += self.read_until_pattern(pattern=new_pattern)
+ # Do not save 'uncommited changes'
+ if uncommit_pattern in output:
+ self.write_channel(self.normalize_cmd("no"))
+ output += self.read_until_pattern(pattern=pattern)
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def save_config(
+ self, cmd: str = "commit", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config"""
+ raise NotImplementedError
diff --git a/netmiko/cisco/cisco_wlc_ssh.py b/netmiko/cisco/cisco_wlc_ssh.py
index 2e65241bd..0dcaf31a7 100644
--- a/netmiko/cisco/cisco_wlc_ssh.py
+++ b/netmiko/cisco/cisco_wlc_ssh.py
@@ -1,18 +1,23 @@
"""Netmiko Cisco WLC support."""
-from __future__ import print_function
-from __future__ import unicode_literals
+from typing import Any, Union, Sequence, TextIO
import time
import re
+import socket
+from netmiko.exceptions import NetmikoAuthenticationException
from netmiko.base_connection import BaseConnection
-from netmiko.py23_compat import string_types
-from netmiko import log
class CiscoWlcSSH(BaseConnection):
"""Netmiko Cisco WLC support."""
- def special_login_handler(self, delay_factor=1):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ # WLC/AireOS has an issue where you can get "No Existing Session" with
+ # the default conn_timeout (so increase conn_timeout to 10-seconds).
+ kwargs.setdefault("conn_timeout", 10)
+ return super().__init__(*args, **kwargs)
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
"""WLC presents with the following on login (in certain OS versions)
login as: user
@@ -25,59 +30,61 @@ def special_login_handler(self, delay_factor=1):
"""
delay_factor = self.select_delay_factor(delay_factor)
i = 0
- time.sleep(delay_factor * .5)
+ time.sleep(delay_factor * 0.5)
output = ""
while i <= 12:
output = self.read_channel()
if output:
- if 'login as' in output or 'User' in output:
+ if "login as" in output or "User:" in output:
+ assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
- elif 'Password' in output:
+ elif "Password" in output:
+ assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
break
time.sleep(delay_factor * 1)
else:
- self.write_channel(self.RETURN)
+ # no output read, sleep and go for one more round of read channel
time.sleep(delay_factor * 1.5)
i += 1
- def send_command_w_enter(self, *args, **kwargs):
- '''
+ def send_command_w_enter(self, *args: Any, **kwargs: Any) -> str:
+ """
For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
Even though pagination is disabled
show run-config also has excessive delays in the output which requires special
handling.
Arguments are the same as send_command_timing() method
- '''
+ """
if len(args) > 1:
raise ValueError("Must pass in delay_factor as keyword argument")
# If no delay_factor use 1 for default value
- delay_factor = kwargs.get('delay_factor', 1)
- kwargs['delay_factor'] = self.select_delay_factor(delay_factor)
- output = self.send_command_timing(*args, **kwargs)
+ delay_factor = kwargs.get("delay_factor", 1)
+ kwargs["delay_factor"] = self.select_delay_factor(delay_factor)
+ output = self._send_command_timing_str(*args, **kwargs)
- if 'Press Enter to' in output:
+ if "Press any key" in output or "Press Enter to" in output:
new_args = list(args)
if len(args) == 1:
new_args[0] = self.RETURN
else:
- kwargs['command_string'] = self.RETURN
- if not kwargs.get('max_loops'):
- kwargs['max_loops'] = 150
+ kwargs["command_string"] = self.RETURN
+ if not kwargs.get("max_loops"):
+ kwargs["max_loops"] = 150
# Send an 'enter'
- output = self.send_command_timing(*new_args, **kwargs)
+ output += self._send_command_timing_str(*new_args, **kwargs)
# WLC has excessive delay after this appears on screen
- if '802.11b Advanced Configuration' in output:
+ if "802.11b Advanced Configuration" in output:
# Defaults to 30 seconds
- time.sleep(kwargs['delay_factor'] * 30)
+ time.sleep(kwargs["delay_factor"] * 30)
not_done = True
i = 1
while not_done and i <= 150:
- time.sleep(kwargs['delay_factor'] * 3)
+ time.sleep(kwargs["delay_factor"] * 3)
i += 1
new_data = ""
new_data = self.read_channel()
@@ -86,79 +93,132 @@ def send_command_w_enter(self, *args, **kwargs):
else:
not_done = False
- strip_prompt = kwargs.get('strip_prompt', True)
+ strip_prompt = kwargs.get("strip_prompt", True)
+ if strip_prompt:
+ # Had to strip trailing prompt twice.
+ output = self.strip_prompt(output)
+ output = self.strip_prompt(output)
+ return output
+
+ def send_command_w_yes(self, *args: Any, **kwargs: Any) -> str:
+ """
+ For 'show interface summary' Cisco WLC adds a
+ 'Would you like to display the next 15 entries?' message
+ Even though pagination is disabled
+ Arguments are the same as send_command_timing() method
+ """
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "(y/n)" in output:
+ output += self._send_command_timing_str("y")
+ strip_prompt = kwargs.get("strip_prompt", True)
if strip_prompt:
# Had to strip trailing prompt twice.
output = self.strip_prompt(output)
output = self.strip_prompt(output)
return output
- def session_preparation(self):
- '''
+ def session_preparation(self) -> None:
+ """
Prepare the session after the connection has been established
Cisco WLC uses "config paging disable" to disable paging
- '''
- self._test_channel_read()
- self.set_base_prompt()
+ """
+ self._test_channel_read(pattern=r"[>#]")
+
+ try:
+ self.set_base_prompt()
+ except ValueError:
+ msg = f"Authentication failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
self.disable_paging(command="config paging disable")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def cleanup(self):
- """Reset WLC back to normal paging."""
+ def cleanup(self, command: str = "logout") -> None:
+ """Reset WLC back to normal paging and gracefully close session."""
self.send_command_timing("config paging enable")
- def check_config_mode(self, check_string='config', pattern=''):
+ # Exit configuration mode
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # End SSH/telnet session
+ self.write_channel(command + self.RETURN)
+ count = 0
+ output = ""
+ while count <= 5:
+ time.sleep(0.5)
+
+ # The connection might be dead at this point.
+ try:
+ output += self.read_channel()
+ except socket.error:
+ break
+
+ # Don't automatically save the config (user's responsibility)
+ if "Would you like to save them now" in output:
+ self._session_log_fin = True
+ self.write_channel("n" + self.RETURN)
+
+ try:
+ self.write_channel(self.RETURN)
+ except socket.error:
+ break
+ count += 1
+
+ def check_config_mode(
+ self, check_string: str = "config", pattern: str = ""
+ ) -> bool:
"""Checks if the device is in configuration mode or not."""
if not pattern:
pattern = re.escape(self.base_prompt)
- return super(CiscoWlcSSH, self).check_config_mode(check_string, pattern)
+ return super().check_config_mode(check_string, pattern)
- def config_mode(self, config_command='config', pattern=''):
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
"""Enter into config_mode."""
- if not pattern:
- pattern = re.escape(self.base_prompt)
- return super(CiscoWlcSSH, self).config_mode(config_command, pattern)
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
- def exit_config_mode(self, exit_config='exit', pattern=''):
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
"""Exit config_mode."""
- if not pattern:
- pattern = re.escape(self.base_prompt)
- return super(CiscoWlcSSH, self).exit_config_mode(exit_config, pattern)
-
- 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):
- """
- Send configuration commands down the SSH channel.
-
- config_commands is an iterable containing all of the configuration commands.
- The commands will be executed one after the other.
-
- Does not automatically exit/enter configuration mode.
- """
- delay_factor = self.select_delay_factor(delay_factor)
- if config_commands is None:
- return ''
- elif isinstance(config_commands, string_types):
- config_commands = (config_commands,)
-
- if not hasattr(config_commands, '__iter__'):
- raise ValueError("Invalid argument passed into send_config_set")
-
- # Send config commands
- for cmd in config_commands:
- self.write_channel(self.normalize_cmd(cmd))
- time.sleep(delay_factor * .5)
-
- # Gather output
- output = self._read_channel_timing(delay_factor=delay_factor, max_loops=max_loops)
- output = self._sanitize_output(output)
- log.debug("{}".format(output))
+ return super().exit_config_mode(exit_config, pattern)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs,
+ )
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Saves Config."""
+ self.enable()
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
return output
-
- def save_config(self, cmd='save config', confirm=True, confirm_response='y'):
- return super(CiscoWlcSSH, self).save_config(cmd=cmd, confirm=confirm,
- confirm_response=confirm_response)
diff --git a/netmiko/cisco/cisco_xr.py b/netmiko/cisco/cisco_xr.py
index c9c3d12ca..44059f58e 100644
--- a/netmiko/cisco/cisco_xr.py
+++ b/netmiko/cisco/cisco_xr.py
@@ -1,107 +1,45 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-
+from typing import Optional, Any, Union, Sequence, TextIO
import re
-import time
-#from logger.cafylog import CafyLog
-#log = CafyLog()
-import logging
-
-
-# This will create a file named 'test.log' in your current directory.
-# It will log all reads and writes on the SSH channel.
-#logging.basicConfig(filename='test_netmiko.log', level=logging.DEBUG)
-#logger = logging.getLogger("netmiko")
-
+import warnings
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
-class CiscoXr(CiscoBaseConnection):
-
- def session_preparation(self):
- """Prepare the session after the connection has been established.
- When router in 'run' (linux $) prompt, switch back to XR prompt
- """
-
- username_pattern=r"(sername)|(ogin)"
- pwd_pattern=r"assword"
- self.set_base_prompt(alt_prompt_terminator='$')
- switch_to_xr_command = 'xr'
- if self.find_prompt().endswith('$'):
- if self._check_for_thinxr_host_prompt() == False:
- self.send_command(switch_to_xr_command, expect_string='#')
- self.base_prompt = self.find_prompt()
- #The below block is added to address getting username/login prompt When
- #the box is reloaded
- elif username_pattern in self.find_prompt():
- elf.send_command(self.username, expect_string=pwd_pattern)
- #time.sleep(1 * delay_factor)
- self.send_command(self.password, expect_string='#')
- #time.sleep(.5 * delay_factor)
- self.base_prompt = self.find_prompt()
- if pri_prompt_terminator in self.base_prompt:
- raise ValueError("Could not go to $prompt")
+class CiscoXrBase(CiscoBaseConnection):
+ def establish_connection(self, width: int = 511, height: int = 511) -> None:
+ """Establish SSH connection to the network device"""
+ super().establish_connection(width=width, height=height)
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # IOS-XR has an issue where it echoes the command even though it hasn't returned the prompt
+ self._test_channel_read(pattern=r"[>#]")
+ cmd = "terminal width 511"
+ self.set_terminal_width(command=cmd, pattern=cmd)
self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
-
- def _check_for_thinxr_host_prompt(self, pri_prompt_terminator='#',
- username_pattern=r"(sername)|(ogin)", pwd_pattern=r"assword",
- delay_factor=1, max_loops=60):
- SSH_RETURN = '\r\n'
- linux_prompt_pattern = "[xr:~]$"
- switch_to_xr_command = 'xr'
- output = ''
- return_msg = ''
- if self.find_prompt() == linux_prompt_pattern:
- self.write_channel(SSH_RETURN + "xr" + SSH_RETURN)
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
- # Search for username pattern / send username and then expect Password
- #pattern and send password and expect xr prompt'#'
- if re.search(username_pattern, output):
- self.send_command(self.username, expect_string=pwd_pattern)
- #time.sleep(1 * delay_factor)
- self.send_command(self.password, expect_string='#')
- #time.sleep(.5 * delay_factor)
- self.base_prompt = self.find_prompt()
- if pri_prompt_terminator in self.base_prompt:
- return True
- else:
- return False
-
-
- def config_mode(self, config_command='config term', pattern='', skip_check=True):
- """
- Enter into configuration mode on remote device.
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
- Cisco IOSXR devices abbreviate the prompt at 20 chars in config mode
- """
- if not pattern:
- #pattern = self.base_prompt[:16]
- #pattern = self.current_prompt[:16]
- pattern = self.base_prompt[:16]
- #pattern = self.current_prompt[:16]
- pattern = pattern + ".*config"
- return super(CiscoBaseConnection, self).config_mode(config_command=config_command,
- pattern=pattern)
-
- def send_config_set(self, config_commands=None, exit_config_mode=True, **kwargs):
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
"""IOS-XR requires you not exit from configuration mode."""
- '''
- return super(CiscoXr, self).send_config_set(config_commands=config_commands,
- exit_config_mode=False, **kwargs)
- '''
- return super(CiscoXr, self).send_config_set(config_commands=config_commands,\
- exit_config_mode=False, **kwargs)
-
- def commit(self, confirm=False, confirm_delay=None, comment='', label='',
- replace=False,best_effort = False, force= False,
- delay_factor=1,
- max_timeout=30, **kwargs):
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ label: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
"""
Commit the candidate configuration.
@@ -114,6 +52,8 @@ def commit(self, confirm=False, confirm_delay=None, comment='', label='',
comment:
command_string = commit comment
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
supported combinations
label and confirm:
command_string = commit label confirmed
@@ -135,181 +75,135 @@ def commit(self, confirm=False, confirm_delay=None, comment='', label='',
Exit of configuration mode with pending changes will cause the changes to be discarded and
an exception to be generated.
"""
- commit_error_dialog_dict = kwargs.get('commit_error_dialog_dict')
- if 'commit_error_dialog_dict' in kwargs:
- kwargs.pop('commit_error_dialog_dict')
- delay_factor = self.select_delay_factor(delay_factor)
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
if confirm and not confirm_delay:
raise ValueError("Invalid arguments supplied to XR commit")
if confirm_delay and not confirm:
raise ValueError("Invalid arguments supplied to XR commit")
if comment and confirm:
raise ValueError("Invalid arguments supplied to XR commit")
-
- # wrap the comment in quotes
- # wrap the comment in quotes
- if comment:
- if '"' in comment:
- raise ValueError("Invalid comment contains double quote")
- comment = '"{0}"'.format(comment)
label = str(label)
- error_marker = 'Failed to'
- alt_error_marker = 'One or more commits have occurred from other'
+ error_marker = "Failed to"
+ alt_error_marker = "One or more commits have occurred from other"
# Select proper command string based on arguments provided
if label:
if comment:
- command_string = 'commit label {0} comment {1}'.format(label, comment)
+ command_string = f"commit label {label} comment {comment}"
elif confirm:
- command_string = 'commit label {0} confirmed {1}'.format(label, str(confirm_delay))
+ command_string = "commit label {} confirmed {}".format(
+ label, str(confirm_delay)
+ )
else:
- command_string = 'commit label {0}'.format(label)
+ command_string = f"commit label {label}"
elif confirm:
- command_string = 'commit confirmed {0}'.format(str(confirm_delay))
+ command_string = f"commit confirmed {str(confirm_delay)}"
elif comment:
- command_string = 'commit comment {0}'.format(comment)
+ command_string = f"commit comment {comment}"
else:
- command_string = 'commit'
- if force:
- command_string = command_string.replace("commit","commit force")
- if best_effort:
- command_string = command_string.replace("commit","commit best-effort")
- if replace:
- command_string = command_string.replace("commit","commit replace")
- print("command string is ",command_string)
+ command_string = "commit"
+
# Enter config mode (if necessary)
- #output = self.config_mode()
- output = ''
- if replace:
- output += self.send_command_timing(command_string, strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- commit_replace_marker = "This commit will replace or remove the entire running configuration"
- if commit_replace_marker in output:
- if 'expect_string' in kwargs:
- kwargs['expect_string'] = r'\)#'
- output += self.send_command_expect("yes", strip_prompt=False, strip_command=False,
- delay_factor=delay_factor, **kwargs)
- return output
-
- else:
- try:
- output += self.send_command_expect(command_string, strip_prompt=False, strip_command=False,
- delay_factor=delay_factor, **kwargs)
- if error_marker in output:
- raise ValueError("Commit failed with the following errors:\n\n{0}".format(output))
- else:
- return output
- except Exception as err:
- output = str(err)
- if commit_error_dialog_dict is not None and alt_error_marker in commit_error_dialog_dict:
- if alt_error_marker in output:
- marker_value = commit_error_dialog_dict[alt_error_marker]
- output += self.send_command_timing(marker_value, strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- return output
- elif alt_error_marker in output:
- # Other commits occurred, don't proceed with commit
- output += self.send_command_timing("no", strip_prompt=False, strip_command=False,
- delay_factor=delay_factor)
- raise ValueError("Commit failed with the following errors:\n\n{0}".format(output))
- else:
- raise err
-
-
- def check_config_mode(self, check_string=')#', pattern=r"[#\$]"):
+ output = self.config_mode()
+
+ # IOS-XR might do this:
+ # This could be a few minutes if your config is large. Confirm? [y/n][confirm]
+ new_data = self._send_command_str(
+ command_string,
+ expect_string=r"(#|onfirm)",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ if "onfirm" in new_data:
+ output += new_data
+ new_data = self._send_command_str(
+ "y",
+ expect_string=r"#",
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+ output += new_data
+ if error_marker in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ if alt_error_marker in output:
+ # Other commits occurred, don't proceed with commit
+ output += self._send_command_timing_str(
+ "no", strip_prompt=False, strip_command=False
+ )
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[#\$]"
+ ) -> bool:
"""Checks if the device is in configuration mode or not.
- IOS-cXR, unfortunately, does this:
+ IOS-XR, unfortunately, does this:
RP/0/RSP0/CPU0:BNG(admin)#
"""
- self.write_channel('\n')
+ self.write_channel(self.RETURN)
output = self.read_until_pattern(pattern=pattern)
# Strip out (admin) so we don't get a false positive with (admin)#
# (admin-config)# would still match.
output = output.replace("(admin)", "")
return check_string in output
-
- def exit_config_mode(self, exit_config='end', skip_check=False):
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "", skip_check=False) -> str:
"""Exit configuration mode."""
- output = ''
-
+ output = ""
if skip_check or self.check_config_mode():
- output = self.send_command_timing(exit_config, strip_prompt=False,
- strip_command=False)
- if "Uncommitted changes found" in output:
- output += self.send_command_timing('no\n', strip_prompt=False, strip_command=False)
-
+ self.write_channel(self.normalize_cmd(exit_config))
+ # 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_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" in output:
+ self.write_channel(self.normalize_cmd("no\n"))
+ output += self.read_until_pattern(pattern=r"[>#]")
+ if not re.search(pattern, output, flags=re.M):
+ output += self.read_until_pattern(pattern=pattern)
if skip_check:
return output
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
- @staticmethod
- def normalize_linefeeds(a_string):
- """Convert '\r\n','\r\r\n', '\n\r', or '\r' to '\n."""
- newline = re.compile(r'(\r\r\n|\r\n|\n\r|\r)')
- return newline.sub('\n', a_string)
-
-class CiscoXrSSH(CiscoXr):
- '''
- CiscoXrSSH is based of CiscoXr -- CiscoBaseConnection
- '''
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+
+class CiscoXrSSH(CiscoXrBase):
+ """Cisco XR SSH driver."""
+
pass
-class CiscoXrTelnet(CiscoXr):
- '''
- CiscoXrTelnet is based of CiscoXr -- CiscoBaseConnection
- '''
+
+class CiscoXrTelnet(CiscoXrBase):
+ """Cisco XR Telnet driver."""
+
def session_preparation(self):
"""Prepare the session after the connection has been established."""
self.set_base_prompt()
- if 'RP Node is not ' in self.find_prompt():
- # Incase of standby - skip rest of section
- return
- self.disable_paging()
- self.set_terminal_width(command='terminal width 511')
- def set_base_prompt(self, pri_prompt_terminator='#',
- alt_prompt_terminator='>', delay_factor=1,
- standby_prompt='RP Node is not ',
- ):
- """
- Sets self.base_prompt
-
- Used as delimiter for stripping of trailing prompt in output.
-
- Should be set to something that is general and applies in multiple contexts. For Cisco
- devices this will be set to router hostname (i.e. prompt without '>' or '#').
-
- This will be set on entering user exec or privileged exec on Cisco, but not when
- entering/exiting config mode.
- """
- prompt = self.find_prompt(delay_factor=delay_factor)
- list_of_valid_prompts = []
- list_of_valid_prompts.append(pri_prompt_terminator)
- list_of_valid_prompts.append(alt_prompt_terminator)
- if standby_prompt in prompt:
- self.base_prompt = prompt
- return self.base_prompt
- if not prompt[-1] in list_of_valid_prompts:
- raise ValueError("Router prompt not found: {0}".format(prompt))
- # Strip off trailing terminator
- self.base_prompt = prompt[:-1]
- return self.base_prompt
-
-class CiscoCxrHa(CiscoXrTelnet):
- def find_prompt(self, delay_factor=1, pattern=r'[a-z0-9]$', telnet_return='\n'):
- return super().find_prompt(delay_factor=delay_factor, pattern=pattern, telnet_return='\r\n')
-
class CiscoXrFileTransfer(CiscoFileTransfer):
"""Cisco IOS-XR SCP File Transfer driver."""
- def process_md5(self, md5_output, pattern=r"^([a-fA-F0-9]+)$"):
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"^([a-fA-F0-9]+)$") -> str:
"""
IOS-XR defaults with timestamps enabled
+
# show md5 file /bootflash:/boot/grub/grub.cfg
Sat Mar 3 17:49:03.596 UTC
c84843f0030efd44b01343fdb8c2e801
@@ -318,26 +212,29 @@ def process_md5(self, md5_output, pattern=r"^([a-fA-F0-9]+)$"):
if match:
return match.group(1)
else:
- raise ValueError("Invalid output from MD5 command: {}".format(md5_output))
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
- def remote_md5(self, base_cmd='show md5 file', remote_file=None):
+ def remote_md5(
+ self, base_cmd: str = "show md5 file", remote_file: Optional[str] = None
+ ) -> str:
"""
IOS-XR for MD5 requires this extra leading /
+
show md5 file /bootflash:/boot/grub/grub.cfg
"""
if remote_file is None:
- if self.direction == 'put':
+ if self.direction == "put":
remote_file = self.dest_file
- elif self.direction == 'get':
+ elif self.direction == "get":
remote_file = self.source_file
# IOS-XR requires both the leading slash and the slash between file-system and file here
- remote_md5_cmd = "{} /{}/{}".format(base_cmd, self.file_system, remote_file)
- dest_md5 = self.ssh_ctl_chan.send_command(remote_md5_cmd, max_loops=1500)
+ remote_md5_cmd = f"{base_cmd} /{self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
dest_md5 = self.process_md5(dest_md5)
return dest_md5
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
diff --git a/netmiko/cisco/cisco_xr_ssh.py b/netmiko/cisco/cisco_xr_ssh.py
deleted file mode 100644
index f3fdf0ff0..000000000
--- a/netmiko/cisco/cisco_xr_ssh.py
+++ /dev/null
@@ -1,3 +0,0 @@
-'''
-CiscoXrSSH is part of cisco_xr.py
-'''
diff --git a/netmiko/cisco_base_connection.py b/netmiko/cisco_base_connection.py
index 23e518057..abd94fa1b 100644
--- a/netmiko/cisco_base_connection.py
+++ b/netmiko/cisco_base_connection.py
@@ -1,314 +1,258 @@
"""CiscoBaseConnection is netmiko SSH class for Cisco and Cisco-like platforms."""
-from __future__ import unicode_literals
-from netmiko.base_connection import BaseConnection
-from netmiko.scp_handler import BaseFileTransfer
-from netmiko.ssh_exception import NetMikoAuthenticationException
-from netmiko import log
+from typing import Optional
import re
import time
+from netmiko.base_connection import BaseConnection
+from netmiko.scp_handler import BaseFileTransfer
+from netmiko.exceptions import NetmikoAuthenticationException
class CiscoBaseConnection(BaseConnection):
"""Base Class for cisco-like behavior."""
- def check_enable_mode(self, check_string='#'):
- """Check if in enable mode. Return boolean."""
- return super(CiscoBaseConnection, self).check_enable_mode(check_string=check_string)
- def enable(self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE):
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Enter enable mode."""
- return super(CiscoBaseConnection, self).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'):
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
"""Exits enable (privileged exec) mode."""
- return super(CiscoBaseConnection, self).exit_enable_mode(exit_command=exit_command)
+ return super().exit_enable_mode(exit_command=exit_command)
- def check_config_mode(self, check_string=')#', pattern=''):
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
"""
Checks if the device is in configuration mode or not.
Cisco IOS devices abbreviate the prompt at 20 chars in config mode
"""
- if not pattern:
- #pattern = self.base_prompt[:16]
- pattern = self.base_prompt[:14]
- return super(CiscoBaseConnection, self).check_config_mode(check_string=check_string,
- pattern=pattern)
-
- def config_mode(self, config_command='config terminal', pattern=''):
- """
- Enter into configuration mode on remote device.
-
- Cisco IOS devices abbreviate the prompt at 20 chars in config mode
- """
- if not pattern:
- pattern = re.escape(self.base_prompt[:16])
- return super(CiscoBaseConnection, self).config_mode(config_command=config_command,
- pattern=pattern)
-
- def exit_config_mode(self, exit_config='end', pattern=''):
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = r"#.*") -> str:
"""Exit from configuration mode."""
- if not pattern:
- #pattern = self.base_prompt[:16]
- #pattern = self.current_prompt[:16]
- pattern = self.base_prompt[:14]
- #pattern = self.current_prompt[:14]
- return super(CiscoBaseConnection, self).exit_config_mode(exit_config=exit_config,
- pattern=pattern)
-
- def serial_login(self, pri_prompt_terminator=r'#\s*$', alt_prompt_terminator=r'>\s*$',
- username_pattern=r"(?:[Uu]ser:|sername|ogin)", pwd_pattern=r"assword",
- delay_factor=1, max_loops=20):
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def serial_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
self.write_channel(self.TELNET_RETURN)
output = self.read_channel()
- if (re.search(pri_prompt_terminator, output, flags=re.M)
- or re.search(alt_prompt_terminator, output, flags=re.M)):
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
return output
else:
- return self.telnet_login(pri_prompt_terminator, alt_prompt_terminator,
- username_pattern, pwd_pattern, delay_factor, max_loops)
-
- def telnet_login(self, pri_prompt_terminator=r'#\s*$', alt_prompt_terminator=r'>\s*$',
- username_pattern=r"(?:[Uu]ser:|sername|ogin|User Name)",
- pwd_pattern=r"assword|ecret",
- delay_factor=1, max_loops=20):
+ return self.telnet_login(
+ pri_prompt_terminator,
+ alt_prompt_terminator,
+ username_pattern,
+ pwd_pattern,
+ delay_factor,
+ max_loops,
+ )
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"\#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
"""Telnet login. Can be username/password or just password."""
- self.TELNET_RETURN = '\n'
delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(1 * delay_factor)
-
- output = ''
- return_msg = ''
- i = 1
-
- is_spitfire = False
-
- while i <= max_loops:
- try:
- log.debug("Reading channel for the first time")
- output = self.read_channel()
- #This below if block is addeed because when the telnet console starts with UserName,
- #self.read_channel which internally calls telnetlib.read_ver_eager() returns empty string
- #So, assign it to self.find_prompt()
- log.debug("Output after reading channel for first time: {}".format(output))
- if output == '':
- time.sleep(2 * delay_factor)
- log.debug("output is empty, doing find_prompt()")
- output=self.find_prompt()
-
- log.debug("Output after doing find_prompt: {}".format(output))
- return_msg += output
-
- #is at spitfire xr prompt
- if re.search('RP/\d+/RP\d+/CPU\d+:\S*#$', output):
- return return_msg
-
- #At Rebooted BMC prompt
- # reboot_bmc_to_bmc_cmd = 'boot'
- rebooted_bmc_prompt_pattern = r"cisco-bmc#"
- if re.search(rebooted_bmc_prompt_pattern, output):
- self.write_channel(self.TELNET_RETURN + "boot" + self.TELNET_RETURN)
- time.sleep(60 * delay_factor)
- self.write_channel(self.TELNET_RETURN)
- output = self.read_channel()
- return_msg += output
- #At BMC prompt
- bmc_prompt_pattern = r"root@spitfire-arm:~#"
- if re.search(bmc_prompt_pattern, output):
- self.write_channel(self.TELNET_RETURN + "\x17" + self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
-
- # Search for linux host prompt pattern [xr:~] or x86 prompt pattern
- linux_prompt_pattern = r"(\[xr:~]\$)|(\[[\w\-]+:~\]\$$)"
- switch_to_xr_command = 'xr'
- x86_prompt_pattern = r"(\S+@xr:~#)|(\S+@ios:~#)"
- if re.search(linux_prompt_pattern, output) or re.search(x86_prompt_pattern, output):
- self.write_channel(self.TELNET_RETURN + "xr" + self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
+ if delay_factor < 1:
+ if not self._legacy_mode and self.fast_cli:
+ delay_factor = 1
- # If previously from xr prompt, if bash was executed to go to linux host prompt,
- # then inorder to go back to xr prompt, no need of xrlogin and password,
- # just do "exit" cmd
- xr_no_login_pattern = "Exec cannot be started from within an existing exec session"
- if re.search(xr_no_login_pattern, output):
- self.write_channel(self.TELNET_RETURN + "exit" + self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
- if pri_prompt_terminator in output or alt_prompt_terminator in output:
- return return_msg
+ time.sleep(1 * delay_factor)
- # If previously from xr prompt, XR not started, must restart XR
- xr_not_started = r"(error while loading shared libraries)|(cannot open shared object)"
- if re.search(xr_not_started, output):
- self.write_channel("initctl start ios-xr.routing.start" + self.TELNET_RETURN)
- time.sleep(60 * delay_factor)
- self.write_channel(self.TELNET_RETURN)
+ output = ""
+ return_msg = ""
+ outer_loops = 3
+ inner_loops = int(max_loops / outer_loops)
+ i = 1
+ for _ in range(outer_loops):
+ while i <= inner_loops:
+ try:
output = self.read_channel()
return_msg += output
-
- # Search for standby console pattern
- standby_pattern=r"RP Node is not ready or active for login"
- if re.search(standby_pattern,output):
- ''' Session is standby state '''
- return return_msg
-
- my_password = self.password
- # Search for username pattern / send username OR
- # If the prompt shows "xr login:", the you can directly login to xr using xr username
- # and password or you can login to linux host, using linux host's username password
- log.debug("Searching for username pattern")
- if re.search(username_pattern, output):
- #print("Username pattern detected, sending Username=", self.username)
- log.debug("Username pattern detected, sending Username={}".format(self.username))
- time.sleep(1)
- bmc_login_pattern = "spitfire-arm login:"
- if re.search(bmc_login_pattern, output):
- my_password = '0penBmc'
- else:
- my_password = self.password
- self.write_channel(self.username + self.TELNET_RETURN)
- time.sleep(1 * delay_factor)
- output = self.read_channel()
- return_msg += output
- log.debug("After sending username, the output pattern is={}".format(output))
- log.debug("________________________________________________")
- #print("After sending username, the output pattern is=", output)
- #print ("__________________________________________")
- else:
- xr_or_host_login_pattern = "xr login:"
- xr_or_host_login_alt_pattern = "ios login:"
- if re.search(xr_or_host_login_pattern, output) or re.search(xr_or_host_login_alt_pattern, output):
- self.write_channel(self.username + self.TELNET_RETURN)
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ self.write_channel(self.username + "\r")
time.sleep(1 * delay_factor)
output = self.read_channel()
return_msg += output
- # Search for password pattern / send password
- if re.search(pwd_pattern, output):
- self.write_channel(my_password + self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
- if (re.search(pri_prompt_terminator, output, flags=re.M) or\
- re.search(alt_prompt_terminator, output, flags=re.M)) and \
- not re.search(x86_prompt_pattern, output):
- return return_msg
-
- if re.search(pwd_pattern, output):
- self.write_channel(my_password + self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- output = self.read_channel()
- return_msg += output
-
-
-
- #Search for "VR0 con0/RP0/CPU0 is now available Press RETURN to get started" pattern
- #on Sunstone devices
- sunstone_pattern = r'Press RETURN to get started\.$'
- if re.search(sunstone_pattern,output):
- print("*****Sunstone pattern detected")
- self.write_channel(self.TELNET_RETURN)
- output = self.read_channel()
-
-
- # Support direct telnet through terminal server
- if re.search(r"initial configuration dialog\? \[yes/no\]: ", output):
- self.write_channel("no" + self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- count = 0
- while count < 15:
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ # Sometimes username/password must be terminated with "\r" and not "\r\n"
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + "\r")
+ time.sleep(0.5 * delay_factor)
output = self.read_channel()
return_msg += output
- if re.search(r"ress RETURN to get started", output):
- output = ""
- break
- time.sleep(2 * delay_factor)
- count += 1
-
- # Check for device with no password configured
- if re.search(r"assword required, but none set", output):
- msg = "Telnet login failed - Password required, but none set: {}".format(
- self.host)
- raise NetMikoAuthenticationException(msg)
-
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Support direct telnet through terminal server
+ if re.search(
+ r"initial configuration dialog\? \[yes/no\]: ", output
+ ):
+ self.write_channel("no" + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ count = 0
+ while count < 15:
+ output = self.read_channel()
+ return_msg += output
+ if re.search(r"ress RETURN to get started", output):
+ output = ""
+ break
+ time.sleep(2 * delay_factor)
+ count += 1
+
+ # Check for device with no password configured
+ if re.search(r"assword required, but none set", output):
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = (
+ "Login failed - Password required, but none set: {}".format(
+ self.host
+ )
+ )
+ raise NetmikoAuthenticationException(msg)
+
+ # Check if proper data received
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
- if re.search(rebooted_bmc_prompt_pattern, output) or re.search(bmc_prompt_pattern, output) or re.search(x86_prompt_pattern, output):
- is_spitfire = True
+ i += 1
- # Check if proper data received
- if (pri_prompt_terminator in output or alt_prompt_terminator in output) and is_spitfire == False:
- return return_msg
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
- self.write_channel(self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
- i += 1
- except EOFError:
- msg = "EOFError Telnet login failed: {0}".format(self.host)
- raise NetMikoAuthenticationException(msg)
+ # Try sending an to restart the login process
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i = 1
# Last try to see if we already logged in
self.write_channel(self.TELNET_RETURN)
- time.sleep(.5 * delay_factor)
+ time.sleep(0.5 * delay_factor)
output = self.read_channel()
return_msg += output
- if (re.search(pri_prompt_terminator, output, flags=re.M)
- or re.search(alt_prompt_terminator, output, flags=re.M)):
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
return return_msg
- msg = "LAST_TRY Telnet login failed: {0}".format(self.host)
- raise NetMikoAuthenticationException(msg)
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
- def cleanup(self):
+ def cleanup(self, command: str = "exit") -> None:
"""Gracefully exit the SSH session."""
try:
- self.exit_config_mode()
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
except Exception:
- # Always try to send 'exit' regardless of whether exit_config_mode works or not.
pass
- self.write_channel("exit" + self.RETURN)
-
- def _autodetect_fs(self, cmd='dir', pattern=r'Directory of (.*)/'):
+ # Always try to send final 'exit' (command)
+ if self.session_log:
+ self.session_log.fin = True
+ self.write_channel(command + self.RETURN)
+
+ def _autodetect_fs(
+ self, cmd: str = "dir", pattern: str = r"Directory of (.*)/"
+ ) -> str:
"""Autodetect the file system on the remote device. Used by SCP operations."""
if not self.check_enable_mode():
- raise ValueError('Must be in enable mode to auto-detect the file-system.')
- output = self.send_command_expect(cmd)
+ raise ValueError("Must be in enable mode to auto-detect the file-system.")
+ output = self._send_command_str(cmd)
match = re.search(pattern, output)
if match:
file_system = match.group(1)
# Test file_system
- cmd = "dir {}".format(file_system)
- output = self.send_command_expect(cmd)
- if '% Invalid' in output or '%Error:' in output:
- raise ValueError("An error occurred in dynamically determining remote file "
- "system: {} {}".format(cmd, output))
+ cmd = f"dir {file_system}"
+ output = self._send_command_str(cmd)
+ if "% Invalid" in output or "%Error:" in output:
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
else:
return file_system
- raise ValueError("An error occurred in dynamically determining remote file "
- "system: {} {}".format(cmd, output))
-
- def save_config(self, cmd='copy running-config startup-config', confirm=False,
- confirm_response=''):
+ raise ValueError(
+ "An error occurred in dynamically determining remote file "
+ "system: {} {}".format(cmd, output)
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Saves Config."""
self.enable()
if confirm:
- output = self.send_command_timing(command_string=cmd)
+ output = self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
if confirm_response:
- output += self.send_command_timing(confirm_response)
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
else:
# Send enter by default
- output += self.send_command_timing(self.RETURN)
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
else:
# Some devices are slow so match on trailing-prompt if you can
- output = self.send_command(command_string=cmd)
+ output = self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
return output
diff --git a/netmiko/citrix/__init__.py b/netmiko/citrix/__init__.py
index cd2372af4..a9aa9a203 100644
--- a/netmiko/citrix/__init__.py
+++ b/netmiko/citrix/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.citrix.netscaler_ssh import NetscalerSSH
-__all__ = ['NetscalerSSH']
+__all__ = ["NetscalerSSH"]
diff --git a/netmiko/citrix/netscaler_ssh.py b/netmiko/citrix/netscaler_ssh.py
index 73b3cb844..b89739fc6 100644
--- a/netmiko/citrix/netscaler_ssh.py
+++ b/netmiko/citrix/netscaler_ssh.py
@@ -1,59 +1,46 @@
-import time
-
+from typing import Optional
+from netmiko.no_config import NoConfig
from netmiko.base_connection import BaseConnection
-class NetscalerSSH(BaseConnection):
- """ Netscaler SSH class. """
+class NetscalerSSH(NoConfig, BaseConnection):
+ """Netscaler SSH class."""
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- # 0 will defer to the global delay factor
- delay_factor = self.select_delay_factor(delay_factor=0)
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
- cmd = "{}set cli mode -page OFF{}".format(self.RETURN, self.RETURN)
+ cmd = f"{self.RETURN}set cli mode -page OFF{self.RETURN}"
self.disable_paging(command=cmd)
- time.sleep(1 * delay_factor)
self.set_base_prompt()
- time.sleep(.3 * delay_factor)
- self.clear_buffer()
- def set_base_prompt(self, pri_prompt_terminator='#',
- alt_prompt_terminator='>', delay_factor=1):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt.
- Netscaler has '>' for the prompt.
+ Netscaler has only '>' for the prompt.
"""
- prompt = self.find_prompt(delay_factor=delay_factor)
- if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
- raise ValueError("Router prompt not found: {}".format(repr(prompt)))
-
- prompt = prompt.strip()
- if len(prompt) == 1:
- self.base_prompt = prompt
- else:
- # Strip off trailing terminator
- self.base_prompt = prompt[:-1]
+ base_prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ # If null-string, set base_prompt to just ">"
+ if not base_prompt:
+ self.base_prompt = pri_prompt_terminator
return self.base_prompt
- def check_config_mode(self):
- """Netscaler devices do not have a config mode."""
- return False
-
- def config_mode(self):
- """Netscaler devices do not have a config mode."""
- return ''
-
- def exit_config_mode(self):
- """Netscaler devices do not have a config mode."""
- return ''
-
- def strip_prompt(self, a_string):
- """ Strip 'Done' from command output """
- output = super(NetscalerSSH, self).strip_prompt(a_string)
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip 'Done' from command output"""
+ output = super().strip_prompt(a_string)
lines = output.split(self.RESPONSE_RETURN)
if "Done" in lines[-1]:
- return 'self.RESPONSE_RETURN'.join(lines[:-1])
+ return self.RESPONSE_RETURN.join(lines[:-1])
else:
return output
diff --git a/tests/__init__.py b/netmiko/cli_tools/__init__.py
similarity index 100%
rename from tests/__init__.py
rename to netmiko/cli_tools/__init__.py
diff --git a/netmiko/cli_tools/netmiko_cfg.py b/netmiko/cli_tools/netmiko_cfg.py
new file mode 100755
index 000000000..f10336e3f
--- /dev/null
+++ b/netmiko/cli_tools/netmiko_cfg.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+"""Return output from single show cmd using Netmiko."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+PY2 = sys.version_info.major == 2
+PY3 = sys.version_info.major == 3
+
+if sys.version_info.major == 3:
+ string_types = (str,)
+ text_type = str
+else:
+ string_types = (basestring,) # noqa
+ text_type = unicode # noqa
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cfg_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ if isinstance(cfg_command, string_types):
+ cfg_command = [cfg_command]
+ output = net_connect.send_config_set(cfg_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Execute single config cmd using Netmiko"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--infile", help="Read commands from file", type=argparse.FileType("r")
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Config command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ if not cli_args.cmd and not cli_args.infile:
+ parser.error("No configuration commands provided.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-cfg v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ if r"\n" in cli_command:
+ cli_command = cli_command.strip()
+ cli_command = cli_command.split(r"\n")
+ elif input:
+ cmd_arg = True
+ command_data = cli_args.infile.read()
+ command_data = command_data.strip()
+ cli_command = command_data.splitlines()
+ else:
+ raise ValueError("No configuration commands provided.")
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/netmiko/cli_tools/netmiko_grep.py b/netmiko/cli_tools/netmiko_grep.py
new file mode 100755
index 000000000..2f101c277
--- /dev/null
+++ b/netmiko/cli_tools/netmiko_grep.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python
+"""Create grep like remote behavior on show run or command output."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import obtain_netmiko_filename, write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = "Grep pattern search on Netmiko output (defaults to running-config)"
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "pattern", nargs="?", help="Pattern to search for", action="store", type=str
+ )
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices or not cli_args.pattern:
+ parser.error("Grep pattern or devices not specified.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-grep v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = cli_args.pattern
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/netmiko/cli_tools/netmiko_show.py b/netmiko/cli_tools/netmiko_show.py
new file mode 100755
index 000000000..4dc546e60
--- /dev/null
+++ b/netmiko/cli_tools/netmiko_show.py
@@ -0,0 +1,221 @@
+#!/usr/bin/env python
+"""Return output from single show cmd using Netmiko."""
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import sys
+import os
+import subprocess
+import threading
+
+try:
+ from Queue import Queue
+except ImportError:
+ from queue import Queue
+from datetime import datetime
+from getpass import getpass
+
+from netmiko import ConnectHandler
+from netmiko.utilities import load_devices, display_inventory
+from netmiko.utilities import obtain_all_devices
+from netmiko.utilities import obtain_netmiko_filename, write_tmp_file, ensure_dir_exists
+from netmiko.utilities import find_netmiko_dir
+from netmiko.utilities import SHOW_RUN_MAPPER
+
+GREP = "/bin/grep"
+if not os.path.exists(GREP):
+ GREP = "/usr/bin/grep"
+NETMIKO_BASE_DIR = "~/.netmiko"
+ERROR_PATTERN = "%%%failed%%%"
+__version__ = "0.1.0"
+
+
+def grepx(files, pattern, grep_options, use_colors=True):
+ """Call system grep"""
+ if not isinstance(files, (list, tuple)):
+ files = [files]
+ if use_colors:
+ grep_options += ["--color=auto"]
+
+ # Make grep output look nicer by 'cd netmiko_full_dir'
+ _, netmiko_full_dir = find_netmiko_dir()
+ os.chdir(netmiko_full_dir)
+ # Convert files to strip off the directory
+ retrieve_file = lambda x: x.split("/")[-1] # noqa
+ files = [retrieve_file(a_file) for a_file in files]
+ files.sort()
+ grep_list = [GREP] + grep_options + [pattern] + files
+ proc = subprocess.Popen(grep_list, shell=False)
+ proc.communicate()
+ return ""
+
+
+def ssh_conn(device_name, a_device, cli_command, output_q):
+ try:
+ net_connect = ConnectHandler(**a_device)
+ net_connect.enable()
+ output = net_connect.send_command_expect(cli_command)
+ net_connect.disconnect()
+ except Exception:
+ output = ERROR_PATTERN
+ output_q.put({device_name: output})
+
+
+def parse_arguments(args):
+ """Parse command-line arguments."""
+ description = (
+ "Return output from single show cmd using Netmiko (defaults to running-config)"
+ )
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ "devices",
+ nargs="?",
+ help="Device or group to connect to",
+ action="store",
+ type=str,
+ )
+ parser.add_argument(
+ "--cmd",
+ help="Remote command to execute",
+ action="store",
+ default=None,
+ type=str,
+ )
+ parser.add_argument("--username", help="Username", action="store", type=str)
+ parser.add_argument("--password", help="Password", action="store_true")
+ parser.add_argument("--secret", help="Enable Secret", action="store_true")
+ parser.add_argument("--use-cache", help="Use cached files", action="store_true")
+ parser.add_argument(
+ "--list-devices", help="List devices from inventory", action="store_true"
+ )
+ parser.add_argument(
+ "--display-runtime", help="Display program runtime", action="store_true"
+ )
+ parser.add_argument(
+ "--hide-failed", help="Hide failed devices", action="store_true"
+ )
+ parser.add_argument("--version", help="Display version", action="store_true")
+ cli_args = parser.parse_args(args)
+ if not cli_args.list_devices and not cli_args.version:
+ if not cli_args.devices:
+ parser.error("Devices not specified.")
+ return cli_args
+
+
+def main_ep():
+ sys.exit(main(sys.argv[1:]))
+
+
+def main(args):
+ start_time = datetime.now()
+ cli_args = parse_arguments(args)
+
+ cli_username = cli_args.username if cli_args.username else None
+ cli_password = getpass() if cli_args.password else None
+ cli_secret = getpass("Enable secret: ") if cli_args.secret else None
+
+ version = cli_args.version
+ if version:
+ print("netmiko-show v{}".format(__version__))
+ return 0
+ list_devices = cli_args.list_devices
+ if list_devices:
+ my_devices = load_devices()
+ display_inventory(my_devices)
+ return 0
+
+ cli_command = cli_args.cmd
+ cmd_arg = False
+ if cli_command:
+ cmd_arg = True
+ device_or_group = cli_args.devices.strip()
+ pattern = r"."
+ use_cached_files = cli_args.use_cache
+ hide_failed = cli_args.hide_failed
+
+ output_q = Queue()
+ my_devices = load_devices()
+ if device_or_group == "all":
+ device_group = obtain_all_devices(my_devices)
+ else:
+ try:
+ devicedict_or_group = my_devices[device_or_group]
+ device_group = {}
+ if isinstance(devicedict_or_group, list):
+ for tmp_device_name in devicedict_or_group:
+ device_group[tmp_device_name] = my_devices[tmp_device_name]
+ else:
+ device_group[device_or_group] = devicedict_or_group
+ except KeyError:
+ return (
+ "Error reading from netmiko devices file."
+ " Device or group not found: {0}".format(device_or_group)
+ )
+
+ # Retrieve output from devices
+ my_files = []
+ failed_devices = []
+ if not use_cached_files:
+ for device_name, a_device in device_group.items():
+ if cli_username:
+ a_device["username"] = cli_username
+ if cli_password:
+ a_device["password"] = cli_password
+ if cli_secret:
+ a_device["secret"] = cli_secret
+ if not cmd_arg:
+ cli_command = SHOW_RUN_MAPPER.get(a_device["device_type"], "show run")
+ my_thread = threading.Thread(
+ target=ssh_conn, args=(device_name, a_device, cli_command, output_q)
+ )
+ my_thread.start()
+ # Make sure all threads have finished
+ main_thread = threading.currentThread()
+ for some_thread in threading.enumerate():
+ if some_thread != main_thread:
+ some_thread.join()
+ # Write files
+ while not output_q.empty():
+ my_dict = output_q.get()
+ netmiko_base_dir, netmiko_full_dir = find_netmiko_dir()
+ ensure_dir_exists(netmiko_base_dir)
+ ensure_dir_exists(netmiko_full_dir)
+ for device_name, output in my_dict.items():
+ file_name = write_tmp_file(device_name, output)
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+ else:
+ for device_name in device_group:
+ file_name = obtain_netmiko_filename(device_name)
+ try:
+ with open(file_name) as f:
+ output = f.read()
+ except IOError:
+ return "Some cache files are missing: unable to use --use-cache option."
+ if ERROR_PATTERN not in output:
+ my_files.append(file_name)
+ else:
+ failed_devices.append(device_name)
+
+ grep_options = []
+ grepx(my_files, pattern, grep_options)
+ if cli_args.display_runtime:
+ print("Total time: {0}".format(datetime.now() - start_time))
+
+ if not hide_failed:
+ if failed_devices:
+ print("\n")
+ print("-" * 20)
+ print("Failed devices:")
+ failed_devices.sort()
+ for device_name in failed_devices:
+ print(" {}".format(device_name))
+ print()
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/netmiko/cloudgenix/__init__.py b/netmiko/cloudgenix/__init__.py
new file mode 100644
index 000000000..b28a30a67
--- /dev/null
+++ b/netmiko/cloudgenix/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.cloudgenix.cloudgenix_ion import CloudGenixIonSSH
+
+__all__ = ["CloudGenixIonSSH"]
diff --git a/netmiko/cloudgenix/cloudgenix_ion.py b/netmiko/cloudgenix/cloudgenix_ion.py
new file mode 100644
index 000000000..0f188a877
--- /dev/null
+++ b/netmiko/cloudgenix/cloudgenix_ion.py
@@ -0,0 +1,46 @@
+from typing import Any, Union, Sequence, TextIO, Optional
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CloudGenixIonSSH(NoConfig, CiscoSSHConnection):
+ def establish_connection(self, width: int = 100, height: int = 1000) -> None:
+ super().establish_connection(width=width, height=height)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.write_channel(self.RETURN)
+ self.set_base_prompt(delay_factor=5)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Cloud Genix ION sets terminal height in establish_connection"""
+ return ""
+
+ def find_prompt(
+ self, delay_factor: float = 1.0, pattern: Optional[str] = None
+ ) -> str:
+ prompt = super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+ prompt = self.strip_backspaces(prompt).strip()
+ return prompt
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ output = super().strip_command(command_string, output)
+ # command_string gets repainted potentially multiple times (grab everything after last one)
+ output = output.split(command_string)[-1]
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
diff --git a/netmiko/coriant/__init__.py b/netmiko/coriant/__init__.py
index 4cfd0163e..53242abbb 100644
--- a/netmiko/coriant/__init__.py
+++ b/netmiko/coriant/__init__.py
@@ -1,3 +1,3 @@
from netmiko.coriant.coriant_ssh import CoriantSSH
-__all__ = ['CoriantSSH']
+__all__ = ["CoriantSSH"]
diff --git a/netmiko/coriant/coriant_ssh.py b/netmiko/coriant/coriant_ssh.py
index 9fa901960..c8e4082e8 100644
--- a/netmiko/coriant/coriant_ssh.py
+++ b/netmiko/coriant/coriant_ssh.py
@@ -1,42 +1,30 @@
-
-from __future__ import unicode_literals
+from typing import Any, Optional
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
from netmiko.cisco_base_connection import CiscoSSHConnection
-class CoriantSSH(CiscoSSHConnection):
- def session_preparation(self):
- self._test_channel_read()
+class CoriantSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>:]")
self.set_base_prompt()
- def check_enable_mode(self, *args, **kwargs):
- raise AttributeError("Coriant devices do not support enable mode!")
-
- def enable(self, *args, **kwargs):
- raise AttributeError("Coriant devices do not support enable mode!")
-
- def exit_enable_mode(self, *args, **kwargs):
- raise AttributeError("Coriant devices do not support enable mode!")
-
- def check_config_mode(self):
- """Coriant devices do not have a config mode."""
- return False
-
- def config_mode(self):
- """Coriant devices do not have a config mode."""
- return ''
-
- def exit_config_mode(self):
- """Coriant devices do not have a config mode."""
- return ''
-
- def set_base_prompt(self, pri_prompt_terminator=':', alt_prompt_terminator='>',
- delay_factor=2):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ":",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 2.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
- super(CoriantSSH, self).set_base_prompt(pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
+ super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
return self.base_prompt
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/dell/__init__.py b/netmiko/dell/__init__.py
index 40d788850..ce095d6dc 100644
--- a/netmiko/dell/__init__.py
+++ b/netmiko/dell/__init__.py
@@ -1,6 +1,20 @@
-from __future__ import unicode_literals
+from netmiko.dell.dell_dnos6 import DellDNOS6SSH
+from netmiko.dell.dell_dnos6 import DellDNOS6Telnet
from netmiko.dell.dell_force10_ssh import DellForce10SSH
+from netmiko.dell.dell_os10_ssh import DellOS10SSH, DellOS10FileTransfer
+from netmiko.dell.dell_sonic_ssh import DellSonicSSH
from netmiko.dell.dell_powerconnect import DellPowerConnectSSH
from netmiko.dell.dell_powerconnect import DellPowerConnectTelnet
+from netmiko.dell.dell_isilon_ssh import DellIsilonSSH
-__all__ = ['DellForce10SSH', 'DellPowerConnectSSH', 'DellPowerConnectTelnet']
+__all__ = [
+ "DellForce10SSH",
+ "DellPowerConnectSSH",
+ "DellPowerConnectTelnet",
+ "DellOS10SSH",
+ "DellSonicSSH",
+ "DellOS10FileTransfer",
+ "DellIsilonSSH",
+ "DellDNOS6SSH",
+ "DellDNOS6Telnet",
+]
diff --git a/netmiko/dell/dell_dnos6.py b/netmiko/dell/dell_dnos6.py
new file mode 100644
index 000000000..e901abe8e
--- /dev/null
+++ b/netmiko/dell/dell_dnos6.py
@@ -0,0 +1,32 @@
+"""Dell N2/3/4000 base driver- supports DNOS6."""
+from netmiko.dell.dell_powerconnect import DellPowerConnectBase
+
+
+class DellDNOS6Base(DellPowerConnectBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class DellDNOS6SSH(DellDNOS6Base):
+ pass
+
+
+class DellDNOS6Telnet(DellDNOS6Base):
+ pass
diff --git a/netmiko/dell/dell_force10_ssh.py b/netmiko/dell/dell_force10_ssh.py
index 0481b9ab1..9ce811f66 100644
--- a/netmiko/dell/dell_force10_ssh.py
+++ b/netmiko/dell/dell_force10_ssh.py
@@ -1,11 +1,17 @@
"""Dell Force10 Driver - supports DNOS9."""
-from __future__ import unicode_literals
from netmiko.cisco_base_connection import CiscoSSHConnection
class DellForce10SSH(CiscoSSHConnection):
"""Dell Force10 Driver - supports DNOS9."""
- def save_config(self, cmd='copy running-configuration startup-configuration', confirm=False):
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Saves Config"""
- return super(DellForce10SSH, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/dell/dell_isilon_ssh.py b/netmiko/dell/dell_isilon_ssh.py
new file mode 100644
index 000000000..dd99b5be6
--- /dev/null
+++ b/netmiko/dell/dell_isilon_ssh.py
@@ -0,0 +1,102 @@
+from typing import Any, Optional
+import time
+import re
+
+from netmiko.base_connection import BaseConnection
+
+
+class DellIsilonSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[#\$]")
+ self._zsh_mode()
+ self.find_prompt()
+ self.set_base_prompt()
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Determine base prompt."""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """Remove Null code"""
+ output = re.sub(r"\x00", "", string_buffer)
+ return super().strip_ansi_escape_codes(output)
+
+ def _zsh_mode(self, prompt_terminator: str = "$") -> None:
+ """Run zsh command to unify the environment"""
+ if self.global_delay_factor < 1:
+ delay_factor = 1.0
+ else:
+ delay_factor = self.global_delay_factor
+ command = self.RETURN + "zsh" + self.RETURN
+ self.write_channel(command)
+ time.sleep(0.25 * delay_factor)
+ self._set_prompt(prompt_terminator)
+ time.sleep(0.25 * delay_factor)
+ self.clear_buffer()
+
+ def _set_prompt(self, prompt_terminator: str = "$") -> None:
+ prompt = f"PROMPT='%m{prompt_terminator}'"
+ command = self.RETURN + prompt + self.RETURN
+ self.write_channel(command)
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Isilon doesn't have paging by default."""
+ return ""
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "sudo su",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ delay_factor = self.select_delay_factor(delay_factor=1)
+ output = ""
+ if not self.check_enable_mode():
+ output += self._send_command_timing_str(
+ cmd, strip_prompt=False, strip_command=False
+ )
+ if re.search(pattern, output, flags=re_flags):
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_pattern(pattern=r"#.*$")
+ time.sleep(1 * delay_factor)
+ self._set_prompt(prompt_terminator="#")
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode")
+ return output
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Use equivalent enable method."""
+ return self.check_enable_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "sudo su",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Use equivalent enable method."""
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
+ """Use equivalent enable method."""
+ return self.exit_enable_mode(exit_command=exit_config)
diff --git a/netmiko/dell/dell_os10_ssh.py b/netmiko/dell/dell_os10_ssh.py
new file mode 100644
index 000000000..4c2ed0d52
--- /dev/null
+++ b/netmiko/dell/dell_os10_ssh.py
@@ -0,0 +1,123 @@
+"""Dell EMC Networking OS10 Driver - supports dellos10."""
+from typing import Any, Optional
+from netmiko.base_connection import BaseConnection
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.scp_handler import BaseFileTransfer
+import os
+import re
+
+
+class DellOS10SSH(CiscoSSHConnection):
+ """Dell EMC Networking OS10 Driver - supports dellos10."""
+
+ def save_config(
+ self,
+ cmd: str = "copy running-configuration startup-configuration",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class DellOS10FileTransfer(BaseFileTransfer):
+ """Dell EMC Networking OS10 SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/home/admin",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+ self.folder_name = "/config"
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_cmd = f'system "ls -l {self.file_system}/{remote_file}"'
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_out.splitlines():
+ if remote_file in line:
+ file_size = line.split()[4]
+ break
+ 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:
+ return int(file_size)
+
+ def remote_space_available(self, search_pattern: str = r"(\d+) bytes free") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f'system "df {self.folder_name}"'
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ for line in remote_output.splitlines():
+ if self.folder_name in line:
+ space_available = line.split()[-3]
+ break
+ return int(space_available)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = r"(.*) (.*)") -> str:
+ return super(DellOS10FileTransfer, DellOS10FileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
+
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
+ """Calculate remote MD5 and returns the hash."""
+ if remote_file is None:
+ if self.direction == "put":
+ remote_file = self.dest_file
+ elif self.direction == "get":
+ remote_file = self.source_file
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+ remote_md5_cmd = f'system "md5sum {self.file_system}/{remote_file}"'
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5)
+ return dest_md5.strip()
+
+ def check_file_exists(self, remote_cmd: str = "dir home") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ search_string = r"Directory contents .*{}".format(self.dest_file)
+ return bool(re.search(search_string, remote_out, flags=re.DOTALL))
+ elif self.direction == "get":
+ return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("self.direction is set to an invalid value")
+
+ def put_file(self) -> None:
+ """SCP copy the file from the local system to the remote device."""
+ destination = f"{self.dest_file}"
+ self.scp_conn.scp_transfer_file(self.source_file, destination)
+ # Must close the SCP connection to get the file written (flush)
+ self.scp_conn.close()
+
+ def get_file(self) -> None:
+ """SCP copy the file from the remote device to local system."""
+ source_file = f"{self.source_file}"
+ self.scp_conn.scp_get_file(source_file, self.dest_file)
+ self.scp_conn.close()
diff --git a/netmiko/dell/dell_powerconnect.py b/netmiko/dell/dell_powerconnect.py
index f85ea22a4..63f2578ec 100644
--- a/netmiko/dell/dell_powerconnect.py
+++ b/netmiko/dell/dell_powerconnect.py
@@ -1,47 +1,53 @@
"""Dell PowerConnect Driver."""
-from __future__ import unicode_literals
+from typing import Optional
from paramiko import SSHClient
import time
from os import path
-from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.cisco_base_connection import CiscoBaseConnection
-class SSHClient_noauth(SSHClient):
- def _auth(self, username, *args):
- self._transport.auth_none(username)
- return
-
-
-class DellPowerConnectBase(CiscoSSHConnection):
+class DellPowerConnectBase(CiscoBaseConnection):
"""Dell PowerConnect Driver."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self.ansi_escape_codes = True
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
+ self.enable()
self.disable_paging(command="terminal datadump")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='#',
- delay_factor=1):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
- prompt = super(DellPowerConnectBase, self).set_base_prompt(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
prompt = prompt.strip()
self.base_prompt = prompt
return self.base_prompt
- def check_config_mode(self, check_string='(config)#'):
+ def check_config_mode(
+ self, check_string: str = "(config)#", pattern: str = ""
+ ) -> bool:
"""Checks if the device is in configuration mode"""
- return super(DellPowerConnectBase, self).check_config_mode(check_string=check_string)
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
- def config_mode(self, config_command='config'):
- """Enter configuration mode."""
- return super(DellPowerConnectBase, self).config_mode(config_command=config_command)
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
class DellPowerConnectSSH(DellPowerConnectBase):
@@ -50,13 +56,15 @@ class DellPowerConnectSSH(DellPowerConnectBase):
To make it work, we have to override the SSHClient _auth method.
If we use login/password, the ssh server use the (none) auth mechanism.
"""
- def _build_ssh_client(self):
+
+ def _build_ssh_client(self) -> SSHClient:
"""Prepare for Paramiko SSH connection.
See base_connection.py file for any updates.
"""
# Create instance of SSHClient object
# If user does not provide SSH key, we use noauth
+ remote_conn_pre: SSHClient
if not self.use_keys:
remote_conn_pre = SSHClient_noauth()
else:
@@ -64,15 +72,15 @@ def _build_ssh_client(self):
# Load host_keys for better SSH security
if self.system_host_keys:
- remote_conn_pre.load_system_host_keys()
+ remote_conn_pre.load_system_host_keys()
if self.alt_host_keys and path.isfile(self.alt_key_file):
- remote_conn_pre.load_host_keys(self.alt_key_file)
+ remote_conn_pre.load_host_keys(self.alt_key_file)
# Default is to automatically add untrusted hosts (make sure appropriate for your env)
remote_conn_pre.set_missing_host_key_policy(self.key_policy)
return remote_conn_pre
- def special_login_handler(self, delay_factor=1):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
"""
Powerconnect presents with the following on login
@@ -82,14 +90,16 @@ def special_login_handler(self, delay_factor=1):
"""
delay_factor = self.select_delay_factor(delay_factor)
i = 0
- time.sleep(delay_factor * .5)
+ time.sleep(delay_factor * 0.5)
output = ""
while i <= 12:
output = self.read_channel()
if output:
- if 'User Name:' in output:
+ if "User Name:" in output:
+ assert isinstance(self.username, str)
self.write_channel(self.username + self.RETURN)
- elif 'Password:' in output:
+ elif "Password:" in output:
+ assert isinstance(self.password, str)
self.write_channel(self.password + self.RETURN)
break
time.sleep(delay_factor * 1)
@@ -100,14 +110,6 @@ def special_login_handler(self, delay_factor=1):
class DellPowerConnectTelnet(DellPowerConnectBase):
- def session_preparation(self):
- """Prepare the session after the connection has been established."""
- self.ansi_escape_codes = True
- self._test_channel_read()
- self.set_base_prompt()
- self.enable()
- self.disable_paging(command="terminal length 0")
- self.set_terminal_width()
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
+ """Dell PowerConnect Telnet Driver."""
+
+ pass
diff --git a/netmiko/dell/dell_powerconnect_ssh.py b/netmiko/dell/dell_powerconnect_ssh.py
deleted file mode 100644
index 12a497db0..000000000
--- a/netmiko/dell/dell_powerconnect_ssh.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""Dell PowerConnect Driver."""
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoSSHConnection
-from paramiko import SSHClient
-import time
-from os import path
-
-
-class SSHClient_noauth(SSHClient):
- def _auth(self, username, *args):
- self._transport.auth_none(username)
- return
-
-
-class DellPowerConnectSSH(CiscoSSHConnection):
- """Dell PowerConnect Driver.
-
- To make it work, we have to override the SSHClient _auth method.
- If we use login/password, the ssh server use the (none) auth mechanism.
- """
-
- def _build_ssh_client(self):
- """Prepare for Paramiko SSH connection.
-
- See base_connection.py file for any updates.
- """
- # Create instance of SSHClient object
- # If user does not provide SSH key, we use noauth
- if not self.use_keys:
- remote_conn_pre = SSHClient_noauth()
- else:
- remote_conn_pre = SSHClient()
-
- # Load host_keys for better SSH security
- if self.system_host_keys:
- remote_conn_pre.load_system_host_keys()
- if self.alt_host_keys and path.isfile(self.alt_key_file):
- remote_conn_pre.load_host_keys(self.alt_key_file)
-
- # Default is to automatically add untrusted hosts (make sure appropriate for your env)
- remote_conn_pre.set_missing_host_key_policy(self.key_policy)
- return remote_conn_pre
-
- def special_login_handler(self, delay_factor=1):
- """
- Powerconnect presents with the following on login
-
- User Name:
-
- Password: ****
- """
- delay_factor = self.select_delay_factor(delay_factor)
- i = 0
- time.sleep(delay_factor * .5)
- output = ""
- while i <= 12:
- output = self.read_channel()
- if output:
- if 'User Name:' in output:
- self.write_channel(self.username + '\n')
- elif 'Password:' in output:
- self.write_channel(self.password + '\n')
- break
- time.sleep(delay_factor * 1)
- else:
- self.write_channel('\n')
- time.sleep(delay_factor * 1.5)
- i += 1
-
- def session_preparation(self):
- """Prepare the session after the connection has been established."""
- self.ansi_escape_codes = True
- self._test_channel_read()
- self.set_base_prompt()
- self.disable_paging(command="terminal datadump")
-
- def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator='#',
- delay_factor=1):
- """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
- prompt = super(DellPowerConnectSSH, self).set_base_prompt(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
- prompt = prompt.strip()
- self.base_prompt = prompt
- return self.base_prompt
-
- def check_config_mode(self, check_string='(config)#'):
- """Checks if the device is in configuration mode"""
- return super(DellPowerConnectSSH, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='config'):
- """Enter configuration mode."""
- return super(DellPowerConnectSSH, self).config_mode(config_command=config_command)
diff --git a/netmiko/dell/dell_powerconnect_telnet.py b/netmiko/dell/dell_powerconnect_telnet.py
deleted file mode 100644
index e9e28cb27..000000000
--- a/netmiko/dell/dell_powerconnect_telnet.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""Dell Telnet Driver."""
-from __future__ import unicode_literals
-
-import time
-from netmiko.cisco_base_connection import CiscoBaseConnection
-from netmiko import log
-
-
-class DellPowerConnectTelnet(CiscoBaseConnection):
- def disable_paging(self, command="terminal length 0", delay_factor=1):
- """Must be in enable mode to disable paging."""
-
- self.enable()
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(delay_factor * .1)
- self.clear_buffer()
- command = self.normalize_cmd(command)
- log.debug("In disable_paging")
- log.debug("Command: {0}".format(command))
- self.write_channel(command)
- output = self.read_until_prompt()
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- log.debug("{0}".format(output))
- log.debug("Exiting disable_paging")
- return output
-
- def telnet_login(self, pri_prompt_terminator='#', alt_prompt_terminator='>',
- username_pattern=r"User:", pwd_pattern=r"assword",
- delay_factor=1, max_loops=60):
- """Telnet login. Can be username/password or just password."""
- super(DellPowerConnectTelnet, self).telnet_login(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- username_pattern=username_pattern,
- pwd_pattern=pwd_pattern,
- delay_factor=delay_factor,
- max_loops=max_loops)
diff --git a/netmiko/dell/dell_sonic_ssh.py b/netmiko/dell/dell_sonic_ssh.py
new file mode 100644
index 000000000..e3a3ad083
--- /dev/null
+++ b/netmiko/dell/dell_sonic_ssh.py
@@ -0,0 +1,40 @@
+"""
+Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution by Dell Technologies Driver
+- supports dellenterprisesonic.
+"""
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+
+
+class DellSonicSSH(NoEnable, CiscoSSHConnection):
+ """
+ Dell EMC PowerSwitch platforms running Enterprise SONiC Distribution
+ by Dell Technologies Driver - supports dellenterprisesonic.
+ """
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>$#]")
+ self._enter_shell()
+ self.disable_paging()
+ self.set_base_prompt(alt_prompt_terminator="$")
+
+ def config_mode(
+ self,
+ config_command: str = "configure terminal",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def _enter_shell(self) -> str:
+ """Enter the sonic-cli Shell."""
+ log.debug("Enter sonic-cli Shell.")
+ return self._send_command_str("sonic-cli", expect_string=r"\#")
+
+ def _return_cli(self) -> str:
+ """Return to the CLI."""
+ return self._send_command_str("exit", expect_string=r"\$")
diff --git a/netmiko/dlink/__init__.py b/netmiko/dlink/__init__.py
new file mode 100644
index 000000000..bd0450af9
--- /dev/null
+++ b/netmiko/dlink/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.dlink.dlink_ds import DlinkDSTelnet, DlinkDSSSH
+
+__all__ = ["DlinkDSTelnet", "DlinkDSSSH"]
diff --git a/netmiko/dlink/dlink_ds.py b/netmiko/dlink/dlink_ds.py
new file mode 100644
index 000000000..00ce1ed2d
--- /dev/null
+++ b/netmiko/dlink/dlink_ds.py
@@ -0,0 +1,39 @@
+from typing import Any
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class DlinkDSBase(NoEnable, NoConfig, CiscoSSHConnection):
+ """Supports D-Link DGS/DES device series (there are some DGS/DES devices that are web-only)"""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.disable_paging(command="disable clipaging")
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Return paging before disconnect"""
+ self.send_command_timing("enable clipaging")
+ return super().cleanup(command=command)
+
+
+class DlinkDSSSH(DlinkDSBase):
+ pass
+
+
+class DlinkDSTelnet(DlinkDSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/eltex/__init__.py b/netmiko/eltex/__init__.py
index e0333bd31..2e1fdedb3 100644
--- a/netmiko/eltex/__init__.py
+++ b/netmiko/eltex/__init__.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
from netmiko.eltex.eltex_ssh import EltexSSH
+from netmiko.eltex.eltex_esr_ssh import EltexEsrSSH
-__all__ = ['EltexSSH']
+__all__ = ["EltexSSH", "EltexEsrSSH"]
diff --git a/netmiko/eltex/eltex_esr_ssh.py b/netmiko/eltex/eltex_esr_ssh.py
new file mode 100644
index 000000000..ddee932f9
--- /dev/null
+++ b/netmiko/eltex/eltex_esr_ssh.py
@@ -0,0 +1,131 @@
+from typing import Optional, Any
+import warnings
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class EltexEsrSSH(CiscoSSHConnection):
+ """Netmiko support for routers Eltex ESR."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal datadump")
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = ""
+ ) -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented (use commit() method)"""
+ raise NotImplementedError
+
+ def commit(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Commit the candidate configuration.
+ Commit the entered configuration.
+ Raise an error and return the failure
+ if the commit fails.
+ default:
+ command_string = commit
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't commit configuration"
+ command_string = "commit"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Commit failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _confirm(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Confirm the candidate configuration.
+ Raise an error and return the failure if the confirm fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Nothing to confirm in configuration"
+ command_string = "confirm"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Confirm failed with following errors:\n\n{}".format(output)
+ )
+ return output
+
+ def _restore(
+ self, read_timeout: float = 120.0, delay_factor: Optional[float] = None
+ ) -> str:
+ """
+ Restore the candidate configuration.
+
+ Raise an error and return the failure if the restore fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Can't find backup of previous configuration!"
+ command_string = "restore"
+
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ output = self._send_command_str(
+ command_string=command_string, read_timeout=read_timeout
+ )
+
+ if error_marker in output:
+ raise ValueError(
+ "Restore failed with following errors:\n\n{}".format(output)
+ )
+ return output
diff --git a/netmiko/eltex/eltex_ssh.py b/netmiko/eltex/eltex_ssh.py
index 8c3b1beff..c38fdae3d 100644
--- a/netmiko/eltex/eltex_ssh.py
+++ b/netmiko/eltex/eltex_ssh.py
@@ -1,21 +1,15 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
+from typing import Any
from netmiko.cisco_base_connection import CiscoSSHConnection
class EltexSSH(CiscoSSHConnection):
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self.ansi_escape_codes = True
- self._test_channel_read()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
- self.disable_paging(command='terminal datadump')
+ self.disable_paging(command="terminal datadump")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/endace/__init__.py b/netmiko/endace/__init__.py
new file mode 100644
index 000000000..355e456af
--- /dev/null
+++ b/netmiko/endace/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.endace.endace_ssh import EndaceSSH
+
+__all__ = ["EndaceSSH"]
diff --git a/netmiko/endace/endace_ssh.py b/netmiko/endace/endace_ssh.py
new file mode 100644
index 000000000..07cb0a8d5
--- /dev/null
+++ b/netmiko/endace/endace_ssh.py
@@ -0,0 +1,58 @@
+from typing import Optional
+from netmiko.cisco_base_connection import CiscoSSHConnection
+import re
+
+
+class EndaceSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="no cli session paging enable")
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config) #", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "conf t", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ output = ""
+ if not self.check_config_mode():
+ output += self._send_command_timing_str(
+ config_command, strip_command=False, strip_prompt=False
+ )
+ if "to enter configuration mode anyway" in output:
+ output += self._send_command_timing_str(
+ "YES", strip_command=False, strip_prompt=False
+ )
+ if not self.check_config_mode():
+ raise ValueError("Failed to enter configuration mode")
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ self.config_mode()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/enterasys/__init__.py b/netmiko/enterasys/__init__.py
index 87a151709..94f7e275d 100644
--- a/netmiko/enterasys/__init__.py
+++ b/netmiko/enterasys/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.enterasys.enterasys_ssh import EnterasysSSH
-__all__ = ['EnterasysSSH']
+__all__ = ["EnterasysSSH"]
diff --git a/netmiko/enterasys/enterasys_ssh.py b/netmiko/enterasys/enterasys_ssh.py
index 9a1b2c83b..79c1c2f8e 100644
--- a/netmiko/enterasys/enterasys_ssh.py
+++ b/netmiko/enterasys/enterasys_ssh.py
@@ -1,20 +1,17 @@
"""Enterasys support."""
-from __future__ import unicode_literals
-import time
+from typing import Any
from netmiko.cisco_base_connection import CiscoSSHConnection
class EnterasysSSH(CiscoSSHConnection):
"""Enterasys support."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Enterasys requires enable mode to disable paging."""
- self._test_channel_read()
+ self._test_channel_read(pattern=r">")
self.set_base_prompt()
self.disable_paging(command="set length 0")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
"""Not Implemented"""
raise NotImplementedError
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..03b17b4c8
--- /dev/null
+++ b/netmiko/ericsson/ericsson_ipos.py
@@ -0,0 +1,146 @@
+"""
+Ericsson Ipos looks like it was RedBack equipment.
+"""
+from typing import Optional, Any, Union, Sequence, TextIO
+import re
+import warnings
+
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class EricssonIposSSH(BaseConnection):
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern=r"terminal")
+ self.disable_paging()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable 15",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "disable") -> str:
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "end", pattern: str = "#") -> str:
+ """
+ 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 send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
+ """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 save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = True,
+ confirm_response: str = "yes",
+ ) -> str:
+ """Saves configuration"""
+ output = ""
+ if confirm:
+ output += self._send_command_timing_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+
+ if confirm_response:
+ output += self._send_command_timing_str(
+ confirm_response, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_timing_str(
+ self.RETURN, strip_prompt=False, strip_command=False
+ )
+ else:
+ output += self._send_command_str(
+ command_string=cmd, strip_prompt=False, strip_command=False
+ )
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+ 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_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ 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/exceptions.py b/netmiko/exceptions.py
new file mode 100644
index 000000000..2a66f01e3
--- /dev/null
+++ b/netmiko/exceptions.py
@@ -0,0 +1,68 @@
+from paramiko.ssh_exception import SSHException
+from paramiko.ssh_exception import AuthenticationException
+
+
+class NetmikoBaseException(Exception):
+ """General base exception except for exceptions that inherit from Paramiko."""
+
+ pass
+
+
+class ConnectionException(NetmikoBaseException):
+ """Generic exception indicating the connection failed."""
+
+ pass
+
+
+class NetmikoTimeoutException(SSHException):
+ """SSH session timed trying to connect to the device."""
+
+ pass
+
+
+NetMikoTimeoutException = NetmikoTimeoutException
+
+
+class NetmikoAuthenticationException(AuthenticationException):
+ """SSH authentication exception based on Paramiko AuthenticationException."""
+
+ pass
+
+
+NetMikoAuthenticationException = NetmikoAuthenticationException
+
+
+class ConfigInvalidException(NetmikoBaseException):
+ """Exception raised for invalid configuration error."""
+
+ pass
+
+
+class WriteException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko write operation."""
+
+ pass
+
+
+class ReadException(NetmikoBaseException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+
+class ReadTimeout(ReadException):
+ """General exception indicating an error occurred during a Netmiko read operation."""
+
+ pass
+
+
+class PatternNotFoundException(Exception):
+ """Raise when Send_command received pattern not found"""
+
+ def __init__(self, *args: list, output: str = '', **kwargs: dict) -> None:
+ """
+ @param output: output of the send_command.
+ This output can help caller to analyze what was wrong with pattern
+ """
+ self.output = output
+ super().__init__(*args, **kwargs)
diff --git a/netmiko/extreme/__init__.py b/netmiko/extreme/__init__.py
index 1074d9428..9dcd04366 100644
--- a/netmiko/extreme/__init__.py
+++ b/netmiko/extreme/__init__.py
@@ -1,6 +1,24 @@
-from __future__ import unicode_literals
-from netmiko.extreme.extreme_exos import ExtremeSSH
-from netmiko.extreme.extreme_exos import ExtremeTelnet
+from netmiko.extreme.extreme_ers_ssh import ExtremeErsSSH
+from netmiko.extreme.extreme_exos import ExtremeExosSSH, ExtremeExosFileTransfer
+from netmiko.extreme.extreme_exos import ExtremeExosTelnet
+from netmiko.extreme.extreme_netiron import ExtremeNetironSSH
+from netmiko.extreme.extreme_netiron import ExtremeNetironTelnet
+from netmiko.extreme.extreme_nos_ssh import ExtremeNosSSH
+from netmiko.extreme.extreme_slx_ssh import ExtremeSlxSSH
+from netmiko.extreme.extreme_tierraos_ssh import ExtremeTierraSSH
+from netmiko.extreme.extreme_vsp_ssh import ExtremeVspSSH
from netmiko.extreme.extreme_wing_ssh import ExtremeWingSSH
-__all__ = ['ExtremeSSH', 'ExtremeWingSSH', 'ExtremeTelnet']
+__all__ = [
+ "ExtremeErsSSH",
+ "ExtremeExosSSH",
+ "ExtremeExosTelnet",
+ "ExtremeExosFileTransfer",
+ "ExtremeNetironSSH",
+ "ExtremeNetironTelnet",
+ "ExtremeNosSSH",
+ "ExtremeSlxSSH",
+ "ExtremeTierraSSH",
+ "ExtremeVspSSH",
+ "ExtremeWingSSH",
+]
diff --git a/netmiko/extreme/extreme_ers_ssh.py b/netmiko/extreme/extreme_ers_ssh.py
new file mode 100644
index 000000000..bc94564ab
--- /dev/null
+++ b/netmiko/extreme/extreme_ers_ssh.py
@@ -0,0 +1,56 @@
+"""Netmiko support for Extreme Ethernet Routing Switch."""
+import time
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+# Extreme ERS presents Enter Ctrl-Y to begin.
+CTRL_Y = "\x19"
+
+
+class ExtremeErsSSH(CiscoSSHConnection):
+ """Netmiko support for Extreme Ethernet Routing Switch."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Extreme ERS presents the following as part of the login process:
+
+ Enter Ctrl-Y to begin.
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+
+ # Handle 'Enter Ctrl-Y to begin'
+ output = ""
+ i = 0
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Ctrl-Y" in output:
+ self.write_channel(CTRL_Y)
+ if "sername" in output:
+ assert isinstance(self.username, str)
+ self.write_channel(self.username + self.RETURN)
+ elif "ssword" in output:
+ assert isinstance(self.password, str)
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(0.5 * delay_factor)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+ i += 1
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/extreme/extreme_exos.py b/netmiko/extreme/extreme_exos.py
index 94e406a81..c78e769d3 100644
--- a/netmiko/extreme/extreme_exos.py
+++ b/netmiko/extreme/extreme_exos.py
@@ -1,25 +1,26 @@
"""Extreme support."""
-from __future__ import unicode_literals
-import time
+import os
+from typing import Any, Callable, Optional, Union, List, Dict
import re
+from netmiko.base_connection import BaseConnection
+from netmiko.no_config import NoConfig
from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.scp_handler import BaseFileTransfer
-class ExtremeBase(CiscoSSHConnection):
- """Extreme support.
+class ExtremeExosBase(NoConfig, CiscoSSHConnection):
+ """Extreme Exos support.
Designed for EXOS >= 15.0
"""
- def session_preparation(self):
- self._test_channel_read()
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
self.set_base_prompt()
self.disable_paging(command="disable clipaging")
self.send_command_timing("disable cli prompting")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def set_base_prompt(self, *args, **kwargs):
+ def set_base_prompt(self, *args: Any, **kwargs: Any) -> str:
"""
Extreme attaches an id to the prompt. The id increases with every command.
It needs to br stripped off to match the prompt. Eg.
@@ -34,48 +35,184 @@ def set_base_prompt(self, *args, **kwargs):
* testhost.4 #
* testhost.5 #
"""
- cur_base_prompt = super(ExtremeBase, self).set_base_prompt(*args, **kwargs)
+ cur_base_prompt = super().set_base_prompt(*args, **kwargs)
# Strip off any leading * or whitespace chars; strip off trailing period and digits
- match = re.search(r'[\*\s]*(.*)\.\d+', cur_base_prompt)
+ match = re.search(r"[\*\s]*(.*)\.\d+", cur_base_prompt)
if match:
self.base_prompt = match.group(1)
return self.base_prompt
else:
return self.base_prompt
- def send_command(self, *args, **kwargs):
+ def send_command(
+ self, *args: Any, **kwargs: Any
+ ) -> Union[str, List[Any], Dict[str, Any]]:
"""Extreme needs special handler here due to the prompt changes."""
# Change send_command behavior to use self.base_prompt
- kwargs.setdefault('auto_find_prompt', False)
+ kwargs.setdefault("auto_find_prompt", False)
# refresh self.base_prompt
self.set_base_prompt()
- return super(ExtremeBase, self).send_command(*args, **kwargs)
-
- def config_mode(self, config_command=''):
- """No configuration mode on Extreme."""
- return ''
-
- def check_config_mode(self, check_string='#'):
- """Checks whether in configuration mode. Returns a boolean."""
- return super(ExtremeBase, self).check_config_mode(check_string=check_string)
-
- def exit_config_mode(self, exit_config=''):
- """No configuration mode on Extreme."""
- return ''
-
- def save_config(self, cmd='save configuration primary', confirm=False):
+ return super().send_command(*args, **kwargs)
+
+ def save_config(
+ self,
+ cmd: str = "save configuration primary",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Saves configuration."""
- return super(ExtremeBase, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
-class ExtremeSSH(ExtremeBase):
+class ExtremeExosSSH(ExtremeExosBase):
pass
-class ExtremeTelnet(ExtremeBase):
- 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(ExtremeTelnet, self).__init__(*args, **kwargs)
+class ExtremeExosTelnet(ExtremeExosBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+
+class ExtremeExosFileTransfer(BaseFileTransfer):
+ """Extreme EXOS SCP File Transfer driver."""
+
+ def __init__(
+ self,
+ ssh_conn: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/usr/local/cfg",
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def remote_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> int:
+ """Return space available on remote device."""
+ remote_cmd = f"ls {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "Invalid pathname" in remote_output
+ or "No such file or directory" in remote_output
+ ):
+ msg = f"Invalid file_system: {self.file_system}"
+ else:
+ match = re.search(search_pattern, remote_output)
+ if match:
+ return int(match.group(1))
+ else:
+ msg = f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ raise ValueError(msg)
+
+ def verify_space_available(self, search_pattern: str = r"(\d+)\s+\d+%$") -> bool:
+ """Verify sufficient space is available on destination file system (return boolean)."""
+ return super().verify_space_available(search_pattern)
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """Check if the dest_file already exists on the file system (return boolean)."""
+ if self.direction == "put":
+ if not remote_cmd:
+ remote_cmd = f"ls {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ return False
+ elif self.dest_file 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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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 = f"ls {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
+ assert isinstance(remote_file, str)
+ escape_file_name = re.escape(remote_file)
+ pattern = r".*({}).*".format(escape_file_name)
+ match = re.search(pattern, remote_out)
+ if match:
+ line = match.group(0)
+ # Format will be: -rw-r--r-- 1 admin admin 3934 Jan 24 03:50 filename
+ # Format will be: "-rw-r--r-- 1 admin admin 3934 Jan 24 2022 filename"
+ file_size = line.split()[4]
+ else:
+ raise IOError("Unable to parse 'ls' output in remote_file_size method")
+ if (
+ "No such file or directory" in remote_out
+ or "Invalid pathname" in remote_out
+ ):
+ raise IOError("Unable to find file on remote system")
+ else:
+ return int(file_size)
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def compare_md5(self) -> bool:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ msg = "EXOS does not support an MD5-hash operation."
+ raise AttributeError(msg)
+
+ def enable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support an enable SCP operation. SCP is always enabled."
+ raise AttributeError(msg)
+
+ def disable_scp(self, cmd: str = "") -> None:
+ msg = "EXOS does not support a disable SCP operation."
+ raise AttributeError(msg)
+
+ def verify_file(self) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
diff --git a/netmiko/extreme/extreme_netiron.py b/netmiko/extreme/extreme_netiron.py
new file mode 100644
index 000000000..d8d646736
--- /dev/null
+++ b/netmiko/extreme/extreme_netiron.py
@@ -0,0 +1,33 @@
+from typing import Any
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeNetironBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="skip-page-display")
+ self.set_terminal_width()
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class ExtremeNetironSSH(ExtremeNetironBase):
+ pass
+
+
+class ExtremeNetironTelnet(ExtremeNetironBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/extreme/extreme_nos_ssh.py b/netmiko/extreme/extreme_nos_ssh.py
new file mode 100644
index 000000000..bf9e8904f
--- /dev/null
+++ b/netmiko/extreme/extreme_nos_ssh.py
@@ -0,0 +1,31 @@
+"""Support for Extreme NOS/VDX."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeNosSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme NOS/VDX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme VDX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/extreme/extreme_slx_ssh.py b/netmiko/extreme/extreme_slx_ssh.py
new file mode 100644
index 000000000..75a3f478a
--- /dev/null
+++ b/netmiko/extreme/extreme_slx_ssh.py
@@ -0,0 +1,31 @@
+"""Support for Extreme SLX."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeSlxSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme SLX."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme SLX."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/extreme/extreme_ssh.py b/netmiko/extreme/extreme_ssh.py
deleted file mode 100644
index 2b4c64ebe..000000000
--- a/netmiko/extreme/extreme_ssh.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""Extreme support."""
-from __future__ import unicode_literals
-
-import re
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class ExtremeSSH(CiscoSSHConnection):
- """Extreme support.
-
- Designed for EXOS >= 15.0
- """
- def session_preparation(self):
- """Extreme requires enable mode to disable paging."""
- self._test_channel_read()
- self.enable()
- self.set_base_prompt()
- self.disable_paging(command="disable clipaging\n")
-
- def set_base_prompt(self, *args, **kwargs):
- """
- Extreme attaches an id to the prompt. The id increases with every command.
- It needs to br stripped off to match the prompt. Eg.
-
- testhost.1 #
- testhost.2 #
- testhost.3 #
-
- If new config is loaded and not saved yet, a '* ' prefix appears before the
- prompt, eg.
-
- * testhost.4 #
- * testhost.5 #
- """
- cur_base_prompt = super(ExtremeSSH, self).set_base_prompt(*args, **kwargs)
- # Strip off any leading * or whitespace chars; strip off trailing period and digits
- match = re.search(r'[\*\s]*(.*)\.\d+', cur_base_prompt)
- if match:
- self.base_prompt = match.group(1)
- return self.base_prompt
- else:
- return self.base_prompt
-
- def send_command(self, *args, **kwargs):
- """Extreme needs special handler here due to the prompt changes."""
-
- # Change send_command behavior to use self.base_prompt
- kwargs.setdefault('auto_find_prompt', False)
-
- # refresh self.base_prompt
- self.set_base_prompt()
- return super(ExtremeSSH, self).send_command(*args, **kwargs)
-
- def config_mode(self, config_command=''):
- """No configuration mode on Extreme."""
- return ''
-
- def check_config_mode(self, check_string='#'):
- """Checks whether in configuration mode. Returns a boolean."""
- return super(ExtremeSSH, self).check_config_mode(check_string=check_string)
-
- def exit_config_mode(self, exit_config=''):
- """No configuration mode on Extreme."""
- return ''
diff --git a/netmiko/extreme/extreme_tierraos_ssh.py b/netmiko/extreme/extreme_tierraos_ssh.py
new file mode 100644
index 000000000..a436e8e6c
--- /dev/null
+++ b/netmiko/extreme/extreme_tierraos_ssh.py
@@ -0,0 +1,31 @@
+"""Support for Extreme TierraOS."""
+import time
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeTierraSSH(NoEnable, CiscoSSHConnection):
+ """Support for Extreme TierraOS."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read(pattern=r"#")
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging(command="terminal length 0")
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Adding a delay after login."""
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.write_channel(self.RETURN)
+ time.sleep(1 * delay_factor)
+
+ def save_config(
+ self,
+ cmd: str = "copy run flash://config-file/startup-config",
+ confirm: bool = False,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for Extreme TierraOS."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/extreme/extreme_vsp_ssh.py b/netmiko/extreme/extreme_vsp_ssh.py
new file mode 100644
index 000000000..8e01a867f
--- /dev/null
+++ b/netmiko/extreme/extreme_vsp_ssh.py
@@ -0,0 +1,23 @@
+"""Extreme Virtual Services Platform Support."""
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class ExtremeVspSSH(CiscoSSHConnection):
+ """Extreme Virtual Services Platform Support."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="terminal more disable")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/extreme/extreme_wing_ssh.py b/netmiko/extreme/extreme_wing_ssh.py
index c026d7e21..061a1ad55 100644
--- a/netmiko/extreme/extreme_wing_ssh.py
+++ b/netmiko/extreme/extreme_wing_ssh.py
@@ -1,16 +1,12 @@
-from __future__ import unicode_literals
-import time
from netmiko.cisco_base_connection import CiscoSSHConnection
class ExtremeWingSSH(CiscoSSHConnection):
"""Extreme WiNG support."""
- def session_preparation(self):
- self.set_base_prompt(pri_prompt_terminator='>',
- alt_prompt_terminator='#',
- delay_factor=2)
+
+ def session_preparation(self) -> None:
+ """Disable paging and set Max term width"""
+ self._test_channel_read(pattern=r">|#")
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512", pattern="terminal")
self.disable_paging(command="no page")
- self.set_terminal_width(command='terminal width 512')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
diff --git a/netmiko/f5/__init__.py b/netmiko/f5/__init__.py
index a6c60f8cc..93891c9e6 100644
--- a/netmiko/f5/__init__.py
+++ b/netmiko/f5/__init__.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
-from netmiko.f5.f5_ltm_ssh import F5LtmSSH
+from netmiko.f5.f5_tmsh_ssh import F5TmshSSH
+from netmiko.f5.f5_linux_ssh import F5LinuxSSH
-__all__ = ['F5LtmSSH']
+__all__ = ["F5TmshSSH", "F5LinuxSSH"]
diff --git a/netmiko/f5/f5_linux_ssh.py b/netmiko/f5/f5_linux_ssh.py
new file mode 100644
index 000000000..341b3fc56
--- /dev/null
+++ b/netmiko/f5/f5_linux_ssh.py
@@ -0,0 +1,5 @@
+from netmiko.linux.linux_ssh import LinuxSSH
+
+
+class F5LinuxSSH(LinuxSSH):
+ pass
diff --git a/netmiko/f5/f5_ltm_ssh.py b/netmiko/f5/f5_ltm_ssh.py
deleted file mode 100644
index 0b7c84a29..000000000
--- a/netmiko/f5/f5_ltm_ssh.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from __future__ import unicode_literals
-import time
-from netmiko.base_connection import BaseConnection
-
-
-class F5LtmSSH(BaseConnection):
-
- def session_preparation(self):
- """Prepare the session after the connection has been established."""
- self._test_channel_read()
- self.set_base_prompt()
- self.tmsh_mode()
- self.set_base_prompt()
- self.disable_paging(command="modify cli preference pager disabled display-threshold 0")
- self.clear_buffer()
- cmd = 'run /util bash -c "stty cols 255"'
- self.set_terminal_width(command=cmd)
-
- def tmsh_mode(self, delay_factor=1):
- """tmsh command is equivalent to config command on F5."""
- delay_factor = self.select_delay_factor(delay_factor)
- self.clear_buffer()
- command = "{}tmsh{}".format(self.RETURN, self.RETURN)
- self.write_channel(command)
- time.sleep(1 * delay_factor)
- self.clear_buffer()
- return None
diff --git a/netmiko/f5/f5_tmsh_ssh.py b/netmiko/f5/f5_tmsh_ssh.py
new file mode 100644
index 000000000..639847a3e
--- /dev/null
+++ b/netmiko/f5/f5_tmsh_ssh.py
@@ -0,0 +1,38 @@
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class F5TmshSSH(NoConfig, BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"#")
+ self.tmsh_mode()
+ self._config_mode = False
+ cmd = 'run /util bash -c "stty cols 255"'
+ self.set_terminal_width(command=cmd, pattern="run")
+ self.disable_paging(
+ command="modify cli preference pager disabled display-threshold 0"
+ )
+
+ def tmsh_mode(self, delay_factor: float = 1.0) -> str:
+ """tmsh command is equivalent to config command on F5."""
+ command = f"{self.RETURN}tmsh{self.RETURN}"
+ output = self._send_command_str(command, expect_string=r"tmos.*#")
+ self.set_base_prompt()
+ return output
+
+ def exit_tmsh(self) -> str:
+ output = self._send_command_str("quit", expect_string=r"#")
+ self.set_base_prompt()
+ return output
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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)
diff --git a/netmiko/flexvnf/__init__.py b/netmiko/flexvnf/__init__.py
new file mode 100644
index 000000000..77d0bc6d6
--- /dev/null
+++ b/netmiko/flexvnf/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.flexvnf.flexvnf_ssh import FlexvnfSSH
+
+__all__ = ["FlexvnfSSH"]
diff --git a/netmiko/flexvnf/flexvnf_ssh.py b/netmiko/flexvnf/flexvnf_ssh.py
new file mode 100644
index 000000000..2ed387c8b
--- /dev/null
+++ b/netmiko/flexvnf/flexvnf_ssh.py
@@ -0,0 +1,203 @@
+from typing import Optional, Any
+import re
+import time
+import warnings
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class FlexvnfSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self._test_channel_read(pattern=r"[\$@>%]")
+ self.enter_cli_mode()
+ self.set_base_prompt()
+ self.set_terminal_width(command="set screen width 511", pattern="set")
+ self.disable_paging(command="set screen length 0")
+
+ def enter_cli_mode(self) -> None:
+ """Check if at shell prompt root@ and go into CLI."""
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ count = 0
+ cur_prompt = ""
+ while count < 50:
+ self.write_channel(self.RETURN)
+ time.sleep(0.1 * delay_factor)
+ cur_prompt = self.read_channel()
+ if re.search(r"admin@", cur_prompt) or re.search(
+ r"\$$", cur_prompt.strip()
+ ):
+ self.write_channel("cli" + self.RETURN)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ break
+ elif ">" in cur_prompt or "%" in cur_prompt:
+ break
+ count += 1
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
+ """Exit configuration mode."""
+ output = ""
+ if self.check_config_mode():
+ output += self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ # if 'Exit with uncommitted changes?' in output:
+ if "uncommitted changes" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ check and (confirm or confirm_dely or comment):
+ Exception
+ confirm_delay and no confirm:
+ Exception
+ confirm:
+ confirm_delay option
+ comment option
+ command_string = commit confirmed or commit confirmed
+ check:
+ command_string = commit check
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if check and (confirm or confirm_delay or comment):
+ raise ValueError("Invalid arguments supplied with commit check")
+
+ if confirm_delay and not confirm:
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "Commit complete."
+ if check:
+ command_string = "commit check"
+ commit_marker = "Validation complete"
+ elif confirm:
+ if confirm_delay:
+ command_string = "commit confirmed " + str(confirm_delay)
+ else:
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
+
+ # wrap the comment in quotes
+ if comment:
+ if '"' in comment:
+ raise ValueError("Invalid comment contains double quote")
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
+
+ if and_quit:
+ command_string += " and-quit"
+
+ # 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_str(
+ command_string,
+ expect_string=prompt,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+ else:
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=True,
+ strip_command=True,
+ read_timeout=read_timeout,
+ )
+
+ if commit_marker not in output:
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """Strip the trailing router prompt from the output."""
+ a_string = super().strip_prompt(*args, **kwargs)
+ return self._strip_context_items(a_string)
+
+ def _strip_context_items(self, a_string: str) -> str:
+ """Strip FLEXVNF-specific output.
+
+ FLEXVNF will also put a configuration context:
+ [edit]
+
+ and various chassis contexts:
+ {master:0}, {backup:1}
+
+ This method removes those lines.
+ """
+ strings_to_strip = [
+ r"admin@lab-pg-dev-cp02v.*",
+ r"\[edit.*\]",
+ r"\[edit\]",
+ r"\[ok\]",
+ r"\[.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
+ ]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[0]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+ return a_string
diff --git a/netmiko/fortinet/__init__.py b/netmiko/fortinet/__init__.py
index 46dfcf526..35d7be570 100644
--- a/netmiko/fortinet/__init__.py
+++ b/netmiko/fortinet/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.fortinet.fortinet_ssh import FortinetSSH
-__all__ = ['FortinetSSH']
+__all__ = ["FortinetSSH"]
diff --git a/netmiko/fortinet/fortinet_ssh.py b/netmiko/fortinet/fortinet_ssh.py
index 793d28311..02afa5187 100644
--- a/netmiko/fortinet/fortinet_ssh.py
+++ b/netmiko/fortinet/fortinet_ssh.py
@@ -1,74 +1,104 @@
-from __future__ import unicode_literals
import paramiko
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
+import re
+from typing import Optional
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
-class FortinetSSH(CiscoSSHConnection):
- def _modify_connection_params(self):
+class FortinetSSH(NoConfig, CiscoSSHConnection):
+ def _modify_connection_params(self) -> None:
"""Modify connection parameters prior to SSH connection."""
- paramiko.Transport._preferred_kex = ('diffie-hellman-group14-sha1',
- 'diffie-hellman-group-exchange-sha1',
- 'diffie-hellman-group-exchange-sha256',
- 'diffie-hellman-group1-sha1',)
+ paramiko_transport = getattr(paramiko, "Transport")
+ paramiko_transport._preferred_kex = (
+ "diffie-hellman-group14-sha1",
+ "diffie-hellman-group-exchange-sha1",
+ "diffie-hellman-group-exchange-sha256",
+ "diffie-hellman-group1-sha1",
+ )
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read()
- self.set_base_prompt(alt_prompt_terminator='$')
+
+ data = self._test_channel_read(pattern="to accept|[#$]")
+ # If "set post-login-banner enable" is set it will require you to press 'a'
+ # to accept the banner before you login. This will accept if it occurs
+ if "to accept" in data:
+ self.write_channel("a\r")
+ self._test_channel_read(pattern=r"[#$]")
+
+ self.set_base_prompt(alt_prompt_terminator="$")
self.disable_paging()
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def disable_paging(self, delay_factor=1):
+ def disable_paging(
+ self,
+ command: str = "terminal length 0",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Disable paging is only available with specific roles so it may fail."""
check_command = "get system status | grep Virtual"
- output = self.send_command_timing(check_command)
+ output = self._send_command_timing_str(check_command)
self.allow_disable_global = True
self.vdoms = False
+ self._output_mode = "more"
- if "Virtual domain configuration: enable" in output:
+ if re.search(r"Virtual domain configuration: (multiple|enable)", output):
self.vdoms = True
vdom_additional_command = "config global"
- output = self.send_command_timing(vdom_additional_command, delay_factor=2)
+ output = self._send_command_timing_str(vdom_additional_command, last_read=3)
if "Command fail" in output:
self.allow_disable_global = False
- self.remote_conn.close()
+ if self.remote_conn is not None:
+ self.remote_conn.close()
self.establish_connection(width=100, height=1000)
- new_output = ''
+ new_output = ""
if self.allow_disable_global:
- disable_paging_commands = ["config system console", "set output standard", "end"]
+ self._retrieve_output_mode()
+ disable_paging_commands = [
+ "config system console",
+ "set output standard",
+ "end",
+ ]
# There is an extra 'end' required if in multi-vdoms are enabled
if self.vdoms:
disable_paging_commands.append("end")
- outputlist = [self.send_command_timing(command, delay_factor=2)
- for command in disable_paging_commands]
+ outputlist = [
+ self._send_command_timing_str(command, last_read=3)
+ for command in disable_paging_commands
+ ]
# Should test output is valid
new_output = self.RETURN.join(outputlist)
return output + new_output
- def cleanup(self):
+ def _retrieve_output_mode(self) -> None:
+ """Save the state of the output mode so it can be reset at the end of the session."""
+ reg_mode = re.compile(r"output\s+:\s+(?P.*)\s+\n")
+ output = self._send_command_str("get system console")
+ result_mode_re = reg_mode.search(output)
+ if result_mode_re:
+ result_mode = result_mode_re.group("mode").strip()
+ if result_mode in ["more", "standard"]:
+ self._output_mode = result_mode
+
+ def cleanup(self, command: str = "exit") -> None:
"""Re-enable paging globally."""
if self.allow_disable_global:
- enable_paging_commands = ["config system console", "set output more", "end"]
+ # Return paging state
+ output_mode_cmd = f"set output {self._output_mode}"
+ enable_paging_commands = ["config system console", output_mode_cmd, "end"]
if self.vdoms:
enable_paging_commands.insert(0, "config global")
# Should test output is valid
for command in enable_paging_commands:
self.send_command_timing(command)
+ return super().cleanup(command=command)
- def config_mode(self, config_command=''):
- """No config mode for Fortinet devices."""
- return ''
-
- def exit_config_mode(self, exit_config=''):
- """No config mode for Fortinet devices."""
- return ''
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(
+ self, cmd: str = "", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/hp/__init__.py b/netmiko/hp/__init__.py
index 46a953d8d..097cb7217 100644
--- a/netmiko/hp/__init__.py
+++ b/netmiko/hp/__init__.py
@@ -1,5 +1,4 @@
-from __future__ import unicode_literals
-from netmiko.hp.hp_procurve_ssh import HPProcurveSSH
-from netmiko.hp.hp_comware_ssh import HPComwareSSH
+from netmiko.hp.hp_procurve import HPProcurveSSH, HPProcurveTelnet
+from netmiko.hp.hp_comware import HPComwareSSH, HPComwareTelnet
-__all__ = ['HPProcurveSSH', 'HPComwareSSH']
+__all__ = ["HPProcurveSSH", "HPProcurveTelnet", "HPComwareSSH", "HPComwareTelnet"]
diff --git a/netmiko/hp/hp_comware.py b/netmiko/hp/hp_comware.py
new file mode 100644
index 000000000..3cfcf0a9c
--- /dev/null
+++ b/netmiko/hp/hp_comware.py
@@ -0,0 +1,140 @@
+import re
+from typing import Union, Sequence, TextIO, Any, Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class HPComwareBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # Comware doesn't have a way to set terminal width which breaks cmd_verify
+ global_cmd_verify = kwargs.get("global_cmd_verify")
+ if global_cmd_verify is None:
+ kwargs["global_cmd_verify"] = False
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ # Comware can have a banner that prompts you to continue
+ # 'Press Y or ENTER to continue, N to exit.'
+ data = self._test_channel_read(pattern=r"to continue|[>\]]")
+ if "continue" in data:
+ self.write_channel("\n")
+ self._test_channel_read(pattern=r"[>\]]")
+
+ self.set_base_prompt()
+ command = self.RETURN + "screen-length disable"
+ self.disable_paging(command=command)
+
+ def config_mode(
+ self, config_command: str = "system-view", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit config mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ read_timeout: Optional[float] = None,
+ delay_factor: Optional[float] = None,
+ max_loops: Optional[int] = None,
+ strip_prompt: bool = False,
+ strip_command: bool = False,
+ config_mode_command: Optional[str] = None,
+ cmd_verify: bool = True,
+ enter_config_mode: bool = True,
+ error_pattern: str = "",
+ terminator: str = r"\]",
+ bypass_commands: Optional[str] = None,
+ ) -> str:
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ read_timeout=read_timeout,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ strip_prompt=strip_prompt,
+ strip_command=strip_command,
+ config_mode_command=config_mode_command,
+ cmd_verify=cmd_verify,
+ enter_config_mode=enter_config_mode,
+ error_pattern=error_pattern,
+ terminator=terminator,
+ bypass_commands=bypass_commands,
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts. For Comware
+ this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off leading character
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def enable(
+ self,
+ cmd: str = "system-view",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """enable mode on Comware is system-view."""
+ return self.config_mode(config_command=cmd)
+
+ def exit_enable_mode(self, exit_command: str = "return") -> str:
+ """enable mode on Comware is system-view."""
+ return self.exit_config_mode(exit_config=exit_command)
+
+ def check_enable_mode(self, check_string: str = "]") -> bool:
+ """enable mode on Comware is system-view."""
+ return self.check_config_mode(check_string=check_string)
+
+ def save_config(
+ self, cmd: str = "save force", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HPComwareSSH(HPComwareBase):
+ pass
+
+
+class HPComwareTelnet(HPComwareBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/hp/hp_comware_ssh.py b/netmiko/hp/hp_comware_ssh.py
deleted file mode 100644
index 76d867084..000000000
--- a/netmiko/hp/hp_comware_ssh.py
+++ /dev/null
@@ -1,82 +0,0 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-from netmiko.cisco_base_connection import CiscoSSHConnection
-
-
-class HPComwareSSH(CiscoSSHConnection):
-
- def session_preparation(self):
- """
- Prepare the session after the connection has been established.
- Extra time to read HP banners.
- """
- delay_factor = self.select_delay_factor(delay_factor=0)
- i = 1
- while i <= 4:
- # Comware can have a banner that prompts you to continue
- # 'Press Y or ENTER to continue, N to exit.'
- time.sleep(.5 * delay_factor)
- self.write_channel("\n")
- i += 1
-
- time.sleep(.3 * delay_factor)
- self.clear_buffer()
- self._test_channel_read(pattern=r'[>\]]')
- self.set_base_prompt()
- command = self.RETURN + "screen-length disable"
- self.disable_paging(command=command)
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def config_mode(self, config_command='system-view'):
- """Enter configuration mode."""
- return super(HPComwareSSH, self).config_mode(config_command=config_command)
-
- def exit_config_mode(self, exit_config='return'):
- """Exit config mode."""
- return super(HPComwareSSH, self).exit_config_mode(exit_config=exit_config)
-
- def check_config_mode(self, check_string=']'):
- """Check whether device is in configuration mode. Return a boolean."""
- return super(HPComwareSSH, self).check_config_mode(check_string=check_string)
-
- def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator=']',
- delay_factor=1):
- """
- Sets self.base_prompt
-
- Used as delimiter for stripping of trailing prompt in output.
-
- Should be set to something that is general and applies in multiple contexts. For Comware
- this will be the router prompt with < > or [ ] stripped off.
-
- This will be set on logging in, but not when entering system-view
- """
- prompt = super(HPComwareSSH, self).set_base_prompt(
- pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
-
- # Strip off leading character
- prompt = prompt[1:]
- prompt = prompt.strip()
- self.base_prompt = prompt
- return self.base_prompt
-
- def enable(self, cmd='system-view'):
- """enable mode on Comware is system-view."""
- return self.config_mode(config_command=cmd)
-
- def exit_enable_mode(self, exit_command='return'):
- """enable mode on Comware is system-view."""
- return self.exit_config_mode(exit_config=exit_command)
-
- def check_enable_mode(self, check_string=']'):
- """enable mode on Comware is system-view."""
- return self.check_config_mode(check_string=check_string)
-
- def save_config(self, cmd='save force', confirm=False):
- """Save Config."""
- return super(HPComwareSSH, self).save_config(cmd=cmd, confirm=confirm)
diff --git a/netmiko/hp/hp_procurve.py b/netmiko/hp/hp_procurve.py
new file mode 100644
index 000000000..0588298d0
--- /dev/null
+++ b/netmiko/hp/hp_procurve.py
@@ -0,0 +1,190 @@
+import re
+import time
+import socket
+from os import path
+from typing import Optional
+
+from paramiko import SSHClient
+from netmiko.ssh_auth import SSHClient_noauth
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+from netmiko.exceptions import ReadTimeout
+
+
+class HPProcurveBase(CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ # HP output contains VT100 escape codes
+ self.ansi_escape_codes = True
+
+ # Procurve over SSH uses 'Press any key to continue'
+ data = self._test_channel_read(pattern=r"(any key to continue|[>#])")
+ if "any key to continue" in data:
+ self.write_channel(self.RETURN)
+ self._test_channel_read(pattern=r"[>#]")
+
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 511", pattern="terminal")
+ command = self.RETURN + "no page"
+ self.disable_paging(command=command)
+
+ def check_config_mode(
+ self, check_string: str = ")#", pattern: str = r"[>#]"
+ ) -> bool:
+ """
+ The pattern is needed as it is not in the parent class.
+
+ Not having this will make each check_config_mode() call take ~2 seconds.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ default_username: str = "manager",
+ ) -> str:
+ """Enter enable mode"""
+
+ if self.check_enable_mode():
+ return ""
+
+ output = ""
+ username_pattern = r"(username|login|user name)"
+ pwd_pattern = pattern
+ prompt_pattern = r"[>#]"
+ full_pattern = rf"(username|login|user name|{pwd_pattern}|{prompt_pattern})"
+
+ # Send the enable command
+ self.write_channel(cmd + self.RETURN)
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the username
+ if re.search(username_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(default_username + self.RETURN)
+ full_pattern = rf"{pwd_pattern}|{prompt_pattern})"
+ new_output = self.read_until_pattern(
+ full_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ # Send the password
+ if re.search(pwd_pattern, new_output, flags=re_flags):
+ output += new_output
+ self.write_channel(self.secret + self.RETURN)
+ new_output = self.read_until_pattern(
+ prompt_pattern, read_timeout=15, re_flags=re_flags
+ )
+
+ output += new_output
+ log.debug(f"{output}")
+ self.clear_buffer()
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def cleanup(self, command: str = "logout") -> None:
+ """Gracefully exit the SSH session."""
+
+ # Exit configuration mode.
+ try:
+ if self.check_config_mode():
+ self.exit_config_mode()
+ except Exception:
+ pass
+
+ # Terminate SSH/telnet session
+ self.write_channel(command + self.RETURN)
+
+ output = ""
+ for _ in range(10):
+
+ # The connection might be dead here.
+ try:
+ # "Do you want to log out"
+ # "Do you want to save the current"
+ pattern = r"Do you want.*"
+ new_output = self.read_until_pattern(pattern, read_timeout=1.5)
+ output += new_output
+
+ if "Do you want to log out" in new_output:
+ self.write_channel("y" + self.RETURN)
+ break
+ elif "Do you want to save the current" in new_output:
+ # Don't automatically save the config (user's responsibility)
+ self.write_channel("n" + self.RETURN)
+ except socket.error:
+ break
+ except ReadTimeout:
+ break
+ except Exception:
+ break
+
+ time.sleep(0.05)
+
+ # Set outside of loop
+ self._session_log_fin = True
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HPProcurveSSH(HPProcurveBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Allow passwordless authentication for HP devices being provisioned."""
+
+ # Create instance of SSHClient object. If no SSH keys and no password, then use noauth
+ remote_conn_pre: SSHClient
+ if not self.use_keys and not self.password:
+ remote_conn_pre = SSHClient_noauth()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+
+class HPProcurveTelnet(HPProcurveBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(Login Name:|sername:)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
diff --git a/netmiko/hp/hp_procurve_ssh.py b/netmiko/hp/hp_procurve_ssh.py
deleted file mode 100644
index fadaa6a59..000000000
--- a/netmiko/hp/hp_procurve_ssh.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-import re
-import time
-import socket
-from netmiko.cisco_base_connection import CiscoSSHConnection
-from netmiko import log
-
-
-class HPProcurveSSH(CiscoSSHConnection):
-
- def session_preparation(self):
- """
- Prepare the session after the connection has been established.
- Procurve uses - 'Press any key to continue'
- """
- delay_factor = self.select_delay_factor(delay_factor=0)
- output = ""
- count = 1
- while count <= 30:
- output += self.read_channel()
- if 'any key to continue' in output:
- self.write_channel(self.RETURN)
- break
- else:
- time.sleep(.33 * delay_factor)
- count += 1
-
- # Try one last time to past "Press any key to continue
- self.write_channel(self.RETURN)
-
- # HP output contains VT100 escape codes
- self.ansi_escape_codes = True
-
- self._test_channel_read(pattern=r'[>#]')
- self.set_base_prompt()
- command = self.RETURN + "no page"
- self.disable_paging(command=command)
- self.set_terminal_width(command='terminal width 511')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def enable(self, cmd='enable', pattern='password', re_flags=re.IGNORECASE,
- default_username='manager'):
- """Enter enable mode"""
- output = self.send_command_timing(cmd)
- if 'username' in output.lower() or 'login name' in output.lower() or \
- 'user name' in output.lower():
- output += self.send_command_timing(default_username)
- if 'password' in output.lower():
- output += self.send_command_timing(self.secret)
- log.debug("{}".format(output))
- self.clear_buffer()
- return output
-
- def cleanup(self):
- """Gracefully exit the SSH session."""
- self.exit_config_mode()
- self.write_channel("logout" + self.RETURN)
- count = 0
- while count <= 5:
- time.sleep(.5)
- output = self.read_channel()
- if 'Do you want to log out' in output:
- self.write_channel("y" + self.RETURN)
- # Don't automatically save the config (user's responsibility)
- elif 'Do you want to save the current' in output:
- self.write_channel("n" + self.RETURN)
- try:
- self.write_channel(self.RETURN)
- except socket.error:
- break
- count += 1
-
- def save_config(self, cmd='write memory', confirm=False):
- """Save Config."""
- return super(HPProcurveSSH, self).save_config(cmd=cmd, confirm=confirm)
diff --git a/netmiko/huawei/__init__.py b/netmiko/huawei/__init__.py
index 9a9a938e4..40b818c63 100644
--- a/netmiko/huawei/__init__.py
+++ b/netmiko/huawei/__init__.py
@@ -1,4 +1,5 @@
-from __future__ import unicode_literals
-from netmiko.huawei.huawei_ssh import HuaweiSSH, HuaweiVrpv8SSH
+from netmiko.huawei.huawei import HuaweiSSH, HuaweiVrpv8SSH
+from netmiko.huawei.huawei import HuaweiTelnet
+from netmiko.huawei.huawei_smartax import HuaweiSmartAXSSH
-__all__ = ['HuaweiSSH', 'HuaweiVrpv8SSH']
+__all__ = ["HuaweiSmartAXSSH", "HuaweiSSH", "HuaweiVrpv8SSH", "HuaweiTelnet"]
diff --git a/netmiko/huawei/huawei.py b/netmiko/huawei/huawei.py
new file mode 100644
index 000000000..12dd7e156
--- /dev/null
+++ b/netmiko/huawei/huawei.py
@@ -0,0 +1,238 @@
+from typing import Optional, Any
+import time
+import re
+import warnings
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.exceptions import NetmikoAuthenticationException
+from netmiko import log
+
+
+class HuaweiBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>\]]")
+ self.set_base_prompt()
+ self.disable_paging(command="screen-length 0 temporary")
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ return super().strip_ansi_escape_codes(output)
+
+ def config_mode(
+ self,
+ config_command: str = "system-view",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "return", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return super().check_config_mode(check_string=check_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "]",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple contexts.
+ For Huawei this will be the router prompt with < > or [ ] stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ # Strip off any leading HRP_. characters for USGv5 HA
+ prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
+
+ # Strip off leading terminator
+ prompt = prompt[1:]
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ log.debug(f"prompt: {self.base_prompt}")
+ return self.base_prompt
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = True, confirm_response: str = "y"
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class HuaweiSSH(HuaweiBase):
+ """Huawei SSH driver."""
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Handle password change request by ignoring it"""
+
+ # Huawei can prompt for password change. Search for that or for normal prompt
+ password_change_prompt = r"((Change now|Please choose))|([\]>]\s*$)"
+ output = self.read_until_pattern(password_change_prompt)
+ if re.search(password_change_prompt, output):
+ self.write_channel("N\n")
+ self.clear_buffer()
+ return None
+
+
+class HuaweiTelnet(HuaweiBase):
+ """Huawei Telnet driver."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"]\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(?:user:|username|login|user name)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """Telnet login for Huawei Devices"""
+
+ delay_factor = self.select_delay_factor(delay_factor)
+ password_change_prompt = r"(Change now|Please choose 'YES' or 'NO').+"
+ combined_pattern = r"({}|{}|{})".format(
+ pri_prompt_terminator, alt_prompt_terminator, password_change_prompt
+ )
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ # Search for username pattern / send username
+ output = self.read_until_pattern(
+ pattern=username_pattern, re_flags=re.I
+ )
+ return_msg += output
+ self.write_channel(self.username + self.TELNET_RETURN)
+
+ # Search for password pattern / send password
+ output = self.read_until_pattern(pattern=pwd_pattern, re_flags=re.I)
+ return_msg += output
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+
+ # Waiting for combined output
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Search for password change prompt, send "N"
+ if re.search(password_change_prompt, output):
+ self.write_channel("N" + self.TELNET_RETURN)
+ output = self.read_until_pattern(pattern=combined_pattern)
+ return_msg += output
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ i += 1
+
+ except EOFError:
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ assert self.remote_conn is not None
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+
+class HuaweiVrpv8SSH(HuaweiSSH):
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ 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: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ if comment:
+ command_string += f' comment "{comment}"'
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"]",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+ return output
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
diff --git a/netmiko/huawei/huawei_smartax.py b/netmiko/huawei/huawei_smartax.py
new file mode 100644
index 000000000..053e4cc5e
--- /dev/null
+++ b/netmiko/huawei/huawei_smartax.py
@@ -0,0 +1,118 @@
+import time
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko import log
+
+
+class HuaweiSmartAXSSH(CiscoBaseConnection):
+ """Supports Huawei SmartAX and OLT."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self._disable_smart_interaction()
+ self.disable_paging()
+
+ def strip_ansi_escape_codes(self, string_buffer: str) -> str:
+ """
+ Huawei does a strange thing where they add a space and then add ESC[1D
+ to move the cursor to the left one.
+ The extra space is problematic.
+ """
+ code_cursor_left = chr(27) + r"\[\d+D"
+ output = string_buffer
+ pattern = rf" {code_cursor_left}"
+ output = re.sub(pattern, "", output)
+
+ log.debug("Stripping ANSI escape codes")
+ log.debug(f"new_output = {output}")
+ log.debug(f"repr = {repr(output)}")
+ return super().strip_ansi_escape_codes(output)
+
+ def _disable_smart_interaction(
+ self, command: str = "undo smart", delay_factor: float = 1.0
+ ) -> None:
+ """Disables the { } prompt to avoid having to sent a 2nd return after each command"""
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(delay_factor * 0.1)
+ self.clear_buffer()
+ command = self.normalize_cmd(command)
+ log.debug("In disable_smart_interaction")
+ log.debug(f"Command: {command}")
+ self.write_channel(command)
+ if self.global_cmd_verify is not False:
+ output = self.read_until_pattern(pattern=re.escape(command.strip()))
+ output = self.read_until_prompt(read_entire_line=True)
+ else:
+ output = self.read_until_prompt(read_entire_line=True)
+ log.debug(f"{output}")
+ log.debug("Exiting disable_smart_interaction")
+
+ def disable_paging(
+ self,
+ command: str = "scroll",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def config_mode(
+ self, config_command: str = "config", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string)
+
+ def exit_config_mode(
+ self, exit_config: str = "return", pattern: str = r"#.*"
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config)
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, re_flags=re_flags, enable_pattern=enable_pattern
+ )
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save Config for HuaweiSSH"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/huawei/huawei_ssh.py b/netmiko/huawei/huawei_ssh.py
deleted file mode 100644
index 2c584a762..000000000
--- a/netmiko/huawei/huawei_ssh.py
+++ /dev/null
@@ -1,122 +0,0 @@
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-import re
-from netmiko.cisco_base_connection import CiscoSSHConnection
-from netmiko import log
-
-
-class HuaweiSSH(CiscoSSHConnection):
-
- 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="screen-length 0 temporary")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def config_mode(self, config_command='system-view'):
- """Enter configuration mode."""
- return super(HuaweiSSH, self).config_mode(config_command=config_command)
-
- def exit_config_mode(self, exit_config='return'):
- """Exit configuration mode."""
- return super(HuaweiSSH, self).exit_config_mode(exit_config=exit_config)
-
- def check_config_mode(self, check_string=']'):
- """Checks whether in configuration mode. Returns a boolean."""
- return super(HuaweiSSH, self).check_config_mode(check_string=check_string)
-
- def check_enable_mode(self, *args, **kwargs):
- """Huawei has no enable mode."""
- pass
-
- def enable(self, *args, **kwargs):
- """Huawei has no enable mode."""
- return ''
-
- def exit_enable_mode(self, *args, **kwargs):
- """Huawei has no enable mode."""
- return ''
-
- def set_base_prompt(self, pri_prompt_terminator='>', alt_prompt_terminator=']',
- delay_factor=1):
- """
- Sets self.base_prompt
-
- Used as delimiter for stripping of trailing prompt in output.
-
- Should be set to something that is general and applies in multiple contexts. For Comware
- this will be the router prompt with < > or [ ] stripped off.
-
- This will be set on logging in, but not when entering system-view
- """
- log.debug("In set_base_prompt")
- delay_factor = self.select_delay_factor(delay_factor)
- self.clear_buffer()
- self.write_channel(self.RETURN)
- time.sleep(.5 * delay_factor)
-
- prompt = self.read_channel()
- prompt = self.normalize_linefeeds(prompt)
-
- # If multiple lines in the output take the last line
- prompt = prompt.split(self.RESPONSE_RETURN)[-1]
- prompt = prompt.strip()
-
- # Check that ends with a valid terminator character
- if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
- raise ValueError("Router prompt not found: {0}".format(prompt))
-
- # Strip off any leading HRP_. characters for USGv5 HA
- prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
-
- # Strip off leading and trailing terminator
- prompt = prompt[1:-1]
- prompt = prompt.strip()
- self.base_prompt = prompt
- log.debug("prompt: {0}".format(self.base_prompt))
-
- return self.base_prompt
-
- def save_config(self, cmd='save', confirm=False, confirm_response=''):
- """ Save Config for HuaweiSSH"""
- return super(HuaweiSSH, self).save_config(cmd=cmd, confirm=confirm)
-
-
-class HuaweiVrpv8SSH(HuaweiSSH):
-
- def commit(self, comment='', delay_factor=1):
- """
- 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)
- error_marker = 'Failed to generate committed config'
- command_string = 'commit'
-
- if comment:
- command_string += ' comment "{}"'.format(comment)
-
- output = self.config_mode()
- output += self.send_command_expect(command_string, strip_prompt=False,
- strip_command=False, delay_factor=delay_factor)
- output += self.exit_config_mode()
-
- if error_marker in output:
- raise ValueError('Commit failed with following errors:\n\n{}'.format(output))
- return output
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
- """Not Implemented"""
- raise NotImplementedError
diff --git a/netmiko/ipinfusion/__init__.py b/netmiko/ipinfusion/__init__.py
new file mode 100644
index 000000000..a6781fe64
--- /dev/null
+++ b/netmiko/ipinfusion/__init__.py
@@ -0,0 +1,6 @@
+from netmiko.ipinfusion.ipinfusion_ocnos import (
+ IpInfusionOcNOSSSH,
+ IpInfusionOcNOSTelnet,
+)
+
+__all__ = ["IpInfusionOcNOSSSH", "IpInfusionOcNOSTelnet"]
diff --git a/netmiko/ipinfusion/ipinfusion_ocnos.py b/netmiko/ipinfusion/ipinfusion_ocnos.py
new file mode 100644
index 000000000..960ef17c7
--- /dev/null
+++ b/netmiko/ipinfusion/ipinfusion_ocnos.py
@@ -0,0 +1,78 @@
+import time
+from typing import Any
+from socket import socket
+
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, TTYPE, Telnet
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class IpInfusionOcNOSBase(CiscoBaseConnection):
+ """Common Methods for IP Infusion OcNOS support."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using write command"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class IpInfusionOcNOSSSH(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS SSH driver."""
+
+ pass
+
+
+class IpInfusionOcNOSTelnet(IpInfusionOcNOSBase):
+ """IP Infusion OcNOS Telnet driver."""
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ For all telnet options, re-implement the default telnetlib behaviour
+ and refuse to handle any options. If the server expresses interest in
+ 'terminal type' option, then reply back with 'xterm' terminal type.
+ """
+ if command == DO and option == TTYPE:
+ tsocket.sendall(IAC + WILL + TTYPE)
+ tsocket.sendall(IAC + SB + TTYPE + b"\0" + b"xterm" + IAC + SE)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"(?:user:|sername|login|user name)",
+ pwd_pattern: str = r"assword:",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ # set callback function to handle telnet options.
+ assert self.remote_conn is not None
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
diff --git a/netmiko/juniper/__init__.py b/netmiko/juniper/__init__.py
index 1a17023b3..fab726fe7 100644
--- a/netmiko/juniper/__init__.py
+++ b/netmiko/juniper/__init__.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
from netmiko.juniper.juniper import JuniperSSH, JuniperTelnet, JuniperFileTransfer
+from netmiko.juniper.juniper_screenos import JuniperScreenOsSSH
-__all__ = ['JuniperSSH', 'JuniperTelnet', 'JuniperFileTransfer']
+__all__ = ["JuniperSSH", "JuniperTelnet", "JuniperFileTransfer", "JuniperScreenOsSSH"]
diff --git a/netmiko/juniper/juniper.py b/netmiko/juniper/juniper.py
index 269b745d2..f2fd19e7d 100644
--- a/netmiko/juniper/juniper.py
+++ b/netmiko/juniper/juniper.py
@@ -1,94 +1,103 @@
-from __future__ import unicode_literals
-
import re
import time
+import warnings
+from typing import Optional, Any
-from netmiko.base_connection import BaseConnection
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
from netmiko.scp_handler import BaseFileTransfer
-class JuniperBase(BaseConnection):
+class JuniperBase(NoEnable, BaseConnection):
"""
Implement methods for interacting with Juniper Networks devices.
- Disables `enable()` and `check_enable_mode()`
methods. Overrides several methods for Juniper-specific compatibility.
"""
- 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()
+ def session_preparation(self) -> None:
+ """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_paging(command="set cli screen-length 0")
- self.set_terminal_width(command='set cli screen-width 511')
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
- def _enter_shell(self):
+ def _enter_shell(self) -> str:
"""Enter the Bourne Shell."""
- return self.send_command('start shell sh', expect_string=r"[\$#]")
+ return self._send_command_str("start shell sh", expect_string=r"[\$#]")
- def _return_cli(self):
+ def _return_cli(self) -> str:
"""Return to the Juniper CLI."""
- return self.send_command('exit', expect_string=r"[#>]")
+ return self._send_command_str("exit", expect_string=r"[#>]")
- def enter_cli_mode(self):
+ def enter_cli_mode(self) -> None:
"""Check if at shell prompt root@ and go into CLI."""
delay_factor = self.select_delay_factor(delay_factor=0)
count = 0
- cur_prompt = ''
+ cur_prompt = ""
while count < 50:
self.write_channel(self.RETURN)
- time.sleep(.1 * delay_factor)
+ time.sleep(0.1 * delay_factor)
cur_prompt = self.read_channel()
- if re.search(r'root@', cur_prompt) or re.search(r"^%$", cur_prompt.strip()):
+ if re.search(r"root@", cur_prompt) or re.search(r"^%$", cur_prompt.strip()):
self.write_channel("cli" + self.RETURN)
- time.sleep(.3 * delay_factor)
+ time.sleep(0.3 * delay_factor)
self.clear_buffer()
break
- elif '>' in cur_prompt or '#' in cur_prompt:
+ elif ">" in cur_prompt or "#" in cur_prompt:
break
count += 1
- def check_enable_mode(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def enable(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def check_config_mode(self, check_string=']'):
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
"""Checks if the device is in configuration mode or not."""
- return super(JuniperBase, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='configure'):
+ return super().check_config_mode(check_string=check_string)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"Entering configuration mode",
+ re_flags: int = 0,
+ ) -> str:
"""Enter configuration mode."""
- return super(JuniperBase, self).config_mode(config_command=config_command)
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
- def exit_config_mode(self, exit_config='exit configuration-mode'):
+ def exit_config_mode(
+ self, exit_config: str = "exit configuration-mode", pattern: str = ""
+ ) -> str:
"""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)
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Exit with uncommitted changes?" in output:
+ output += self._send_command_timing_str(
+ "yes", strip_prompt=False, strip_command=False
+ )
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
- def commit(self, confirm=False, confirm_delay=None, check=False, comment='',
- and_quit=False, delay_factor=1):
+ def commit(
+ self,
+ confirm: bool = False,
+ confirm_delay: Optional[int] = None,
+ check: bool = False,
+ comment: str = "",
+ and_quit: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
"""
Commit the candidate configuration.
@@ -110,62 +119,67 @@ def commit(self, confirm=False, confirm_delay=None, check=False, comment='',
check:
command_string = commit check
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
"""
- delay_factor = self.select_delay_factor(delay_factor)
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
if check and (confirm or confirm_delay or comment):
raise ValueError("Invalid arguments supplied with commit check")
-
if confirm_delay and not confirm:
- raise ValueError("Invalid arguments supplied to commit method both confirm and check")
+ raise ValueError(
+ "Invalid arguments supplied to commit method both confirm and check"
+ )
# Select proper command string based on arguments provided
- command_string = 'commit'
- commit_marker = 'commit complete'
+ command_string = "commit"
+ commit_marker = "commit complete"
if check:
- command_string = 'commit check'
- commit_marker = 'configuration check succeeds'
+ command_string = "commit check"
+ commit_marker = "configuration check succeeds"
elif confirm:
if confirm_delay:
- command_string = 'commit confirmed ' + str(confirm_delay)
+ command_string = "commit confirmed " + str(confirm_delay)
else:
- command_string = 'commit confirmed'
- commit_marker = 'commit confirmed will be automatically rolled back in'
+ command_string = "commit confirmed"
+ commit_marker = "commit confirmed will be automatically rolled back in"
# wrap the comment in quotes
if comment:
if '"' in comment:
raise ValueError("Invalid comment contains double quote")
- comment = '"{0}"'.format(comment)
- command_string += ' comment ' + comment
+ comment = f'"{comment}"'
+ command_string += " comment " + comment
if and_quit:
- command_string += ' and-quit'
+ command_string += " and-quit"
# 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)
- else:
- output += self.send_command_expect(command_string, strip_prompt=False,
- strip_command=False, delay_factor=delay_factor)
+
+ expect_string = re.escape(self.base_prompt) if and_quit else None
+
+ output += self._send_command_str(
+ command_string,
+ expect_string=expect_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
if commit_marker not in output:
- raise ValueError("Commit failed with the following errors:\n\n{0}"
- .format(output))
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
return output
- def strip_prompt(self, *args, **kwargs):
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
"""Strip the trailing router prompt from the output."""
- a_string = super(JuniperBase, self).strip_prompt(*args, **kwargs)
+ a_string = super().strip_prompt(*args, **kwargs)
return self.strip_context_items(a_string)
- def strip_context_items(self, a_string):
+ def strip_context_items(self, a_string: str) -> str:
"""Strip Juniper-specific output.
Juniper will also put a configuration context:
@@ -177,12 +191,12 @@ def strip_context_items(self, a_string):
This method removes those lines.
"""
strings_to_strip = [
- r'\[edit.*\]',
- r'\{master:.*\}',
- r'\{backup:.*\}',
- r'\{line.*\}',
- r'\{primary.*\}',
- r'\{secondary.*\}',
+ r"\[edit.*\]",
+ r"\{master:.*\}",
+ r"\{backup:.*\}",
+ r"\{line.*\}",
+ r"\{primary.*\}",
+ r"\{secondary.*\}",
]
response_list = a_string.split(self.RESPONSE_RETURN)
@@ -193,45 +207,74 @@ def strip_context_items(self, a_string):
return self.RESPONSE_RETURN.join(response_list[:-1])
return a_string
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
class JuniperSSH(JuniperBase):
pass
class JuniperTelnet(JuniperBase):
- 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(JuniperTelnet, self).__init__(*args, **kwargs)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
class JuniperFileTransfer(BaseFileTransfer):
"""Juniper SCP File Transfer driver."""
- def __init__(self, ssh_conn, source_file, dest_file, file_system="/var/tmp", direction='put'):
- return super(JuniperFileTransfer, self).__init__(ssh_conn=ssh_conn,
- source_file=source_file,
- dest_file=dest_file,
- file_system=file_system,
- direction=direction)
-
- def remote_space_available(self, search_pattern=""):
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
"""Return space available on remote device."""
return self._remote_space_available_unix(search_pattern=search_pattern)
- def check_file_exists(self, remote_cmd=""):
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
return self._check_file_exists_unix(remote_cmd=remote_cmd)
- def remote_file_size(self, remote_cmd="", remote_file=None):
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""Get the file size of the remote file."""
- return self._remote_file_size_unix(remote_cmd=remote_cmd, remote_file=remote_file)
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
- def remote_md5(self, base_cmd='file checksum md5', remote_file=None):
- return super(JuniperFileTransfer, self).remote_md5(base_cmd=base_cmd,
- remote_file=remote_file)
+ def remote_md5(
+ self, base_cmd: str = "file checksum md5", remote_file: Optional[str] = None
+ ) -> str:
+ return super().remote_md5(base_cmd=base_cmd, remote_file=remote_file)
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
diff --git a/netmiko/juniper/juniper_screenos.py b/netmiko/juniper/juniper_screenos.py
new file mode 100644
index 000000000..09e1a1b73
--- /dev/null
+++ b/netmiko/juniper/juniper_screenos.py
@@ -0,0 +1,32 @@
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.base_connection import BaseConnection
+
+
+class JuniperScreenOsSSH(NoEnable, NoConfig, BaseConnection):
+ """
+ Implement methods for interacting with Juniper ScreenOS devices.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ ScreenOS can be configured to require: Accept this agreement y/[n]
+ """
+ terminator = r"\->"
+ pattern = rf"(Accept this|{terminator})"
+ data = self._test_channel_read(pattern=pattern)
+ if "Accept this" in data:
+ self.write_channel("y")
+ data += self._test_channel_read(pattern=terminator)
+
+ self.set_base_prompt()
+ self.disable_paging(command="set console page 0")
+
+ def save_config(
+ self,
+ cmd: str = "save config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config."""
+ return self._send_command_str(command_string=cmd)
diff --git a/netmiko/juniper/juniper_ssh.py b/netmiko/juniper/juniper_ssh.py
deleted file mode 100644
index ba6227b9d..000000000
--- a/netmiko/juniper/juniper_ssh.py
+++ /dev/null
@@ -1,184 +0,0 @@
-from __future__ import unicode_literals
-
-import re
-import time
-
-from netmiko.base_connection import BaseConnection
-
-
-class JuniperSSH(BaseConnection):
- """
- Implement methods for interacting with Juniper Networks devices.
-
- Disables `enable()` and `check_enable_mode()`
- methods. Overrides several methods for Juniper-specific compatibility.
- """
- 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()
- self.enter_cli_mode()
- self.set_base_prompt()
- self.disable_paging(command="set cli screen-length 0\n")
- self.set_terminal_width(command='set cli screen-width 511')
-
- def enter_cli_mode(self):
- """Check if at shell prompt root@ and go into CLI."""
- delay_factor = self.select_delay_factor(delay_factor=0)
- count = 0
- cur_prompt = ''
- while count < 50:
- self.write_channel("\n")
- time.sleep(.1 * delay_factor)
- cur_prompt = self.read_channel()
- if re.search(r'root@', cur_prompt):
- self.write_channel("cli\n")
- time.sleep(.3 * delay_factor)
- self.clear_buffer()
- break
- elif '>' in cur_prompt or '#' in cur_prompt:
- break
- count += 1
-
- def check_enable_mode(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def enable(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on Juniper."""
- pass
-
- def check_config_mode(self, check_string=']'):
- """Checks if the device is in configuration mode or not."""
- return super(JuniperSSH, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='configure'):
- """Enter configuration mode."""
- return super(JuniperSSH, self).config_mode(config_command=config_command)
-
- def exit_config_mode(self, exit_config='exit configuration-mode'):
- """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 commit(self, confirm=False, confirm_delay=None, check=False, comment='',
- and_quit=False, 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
-
- default:
- command_string = commit
- check and (confirm or confirm_dely or comment):
- Exception
- confirm_delay and no confirm:
- Exception
- confirm:
- confirm_delay option
- comment option
- command_string = commit confirmed or commit confirmed
- check:
- command_string = commit check
-
- """
- delay_factor = self.select_delay_factor(delay_factor)
-
- if check and (confirm or confirm_delay or comment):
- raise ValueError("Invalid arguments supplied with commit check")
-
- if confirm_delay and not confirm:
- raise ValueError("Invalid arguments supplied to commit method both confirm and check")
-
- # Select proper command string based on arguments provided
- command_string = 'commit'
- commit_marker = 'commit complete'
- if check:
- command_string = 'commit check'
- commit_marker = 'configuration check succeeds'
- elif confirm:
- if confirm_delay:
- command_string = 'commit confirmed ' + str(confirm_delay)
- else:
- command_string = 'commit confirmed'
- commit_marker = 'commit confirmed will be automatically rolled back in'
-
- # wrap the comment in quotes
- if comment:
- if '"' in comment:
- raise ValueError("Invalid comment contains double quote")
- comment = '"{0}"'.format(comment)
- command_string += ' comment ' + comment
-
- if and_quit:
- command_string += ' and-quit'
-
- # 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)
- else:
- 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("Commit failed with the following errors:\n\n{0}"
- .format(output))
-
- return output
-
- def strip_prompt(self, *args, **kwargs):
- """Strip the trailing router prompt from the output."""
- a_string = super(JuniperSSH, self).strip_prompt(*args, **kwargs)
- return self.strip_context_items(a_string)
-
- @staticmethod
- def strip_context_items(a_string):
- """Strip Juniper-specific output.
-
- Juniper will also put a configuration context:
- [edit]
-
- and various chassis contexts:
- {master:0}, {backup:1}
-
- This method removes those lines.
- """
- strings_to_strip = [
- r'\[edit.*\]',
- r'\{master:.*\}',
- r'\{backup:.*\}',
- r'\{line.*\}',
- r'\{primary.*\}',
- r'\{secondary.*\}',
- ]
-
- response_list = a_string.split('\n')
- last_line = response_list[-1]
-
- for pattern in strings_to_strip:
- if re.search(pattern, last_line):
- return "\n".join(response_list[:-1])
-
- return a_string
diff --git a/netmiko/keymile/__init__.py b/netmiko/keymile/__init__.py
new file mode 100644
index 000000000..d96095cfb
--- /dev/null
+++ b/netmiko/keymile/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.keymile.keymile_ssh import KeymileSSH
+from netmiko.keymile.keymile_nos_ssh import KeymileNOSSSH
+
+__all__ = ["KeymileSSH", "KeymileNOSSSH"]
diff --git a/netmiko/keymile/keymile_nos_ssh.py b/netmiko/keymile/keymile_nos_ssh.py
new file mode 100644
index 000000000..39a35791f
--- /dev/null
+++ b/netmiko/keymile/keymile_nos_ssh.py
@@ -0,0 +1,34 @@
+import time
+import re
+
+
+from netmiko.cisco.cisco_ios import CiscoIosBase
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class KeymileNOSSSH(CiscoIosBase):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.set_base_prompt()
+ self.disable_paging()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def _test_channel_read(self, count: int = 40, pattern: str = "") -> str:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ output = super()._test_channel_read(count=count, pattern=pattern)
+ pattern = r"Login incorrect"
+ if re.search(pattern, output):
+ self.paramiko_cleanup()
+ msg = "Authentication failure: unable to connect"
+ msg += f"{self.device_type} {self.host}:{self.port}"
+ msg += self.RESPONSE_RETURN + "Login incorrect"
+ raise NetmikoAuthenticationException(msg)
+ else:
+ return output
+
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """Since Keymile NOS always returns True on paramiko.connect() we
+ check the output for substring Login incorrect after connecting."""
+ self._test_channel_read(pattern=r"(>|Login incorrect)")
diff --git a/netmiko/keymile/keymile_ssh.py b/netmiko/keymile/keymile_ssh.py
new file mode 100644
index 000000000..cd52b47e4
--- /dev/null
+++ b/netmiko/keymile/keymile_ssh.py
@@ -0,0 +1,43 @@
+from typing import Any, Optional
+import time
+
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco.cisco_ios import CiscoIosBase
+
+
+class KeymileSSH(NoEnable, NoConfig, CiscoIosBase):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("default_enter", "\r\n")
+ super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r">")
+ self.set_base_prompt()
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Keymile does not use paging."""
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Remove appending empty line and prompt from output"""
+ a_string = a_string[:-1]
+ return super().strip_prompt(a_string=a_string)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """set prompt termination to >"""
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
diff --git a/netmiko/linux/__init__.py b/netmiko/linux/__init__.py
index 5dcf67176..ccb938cf7 100644
--- a/netmiko/linux/__init__.py
+++ b/netmiko/linux/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.linux.linux_ssh import LinuxSSH, LinuxFileTransfer
-__all__ = ['LinuxSSH', 'LinuxFileTransfer']
+__all__ = ["LinuxSSH", "LinuxFileTransfer"]
diff --git a/netmiko/linux/linux_ssh.py b/netmiko/linux/linux_ssh.py
index b08425e99..7c839971f 100644
--- a/netmiko/linux/linux_ssh.py
+++ b/netmiko/linux/linux_ssh.py
@@ -1,101 +1,139 @@
-from __future__ import unicode_literals
-
+from typing import Any, Optional, TYPE_CHECKING, Union, Sequence, TextIO
+import os
import re
import socket
import time
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
from netmiko.cisco_base_connection import CiscoSSHConnection
from netmiko.cisco_base_connection import CiscoFileTransfer
-from netmiko.ssh_exception import NetMikoTimeoutException
+from netmiko.exceptions import NetmikoTimeoutException
+LINUX_PROMPT_PRI = os.getenv("NETMIKO_LINUX_PROMPT_PRI", "$")
+LINUX_PROMPT_ALT = os.getenv("NETMIKO_LINUX_PROMPT_ALT", "#")
+LINUX_PROMPT_ROOT = os.getenv("NETMIKO_LINUX_PROMPT_ROOT", "#")
-class LinuxSSH(CiscoSSHConnection):
- def session_preparation(self):
+class LinuxSSH(CiscoSSHConnection):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self.ansi_escape_codes = True
- return super(LinuxSSH, self).session_preparation()
+ return super().session_preparation()
- def _enter_shell(self):
+ def _enter_shell(self) -> str:
"""Already in shell."""
- return ''
+ return ""
- def _return_cli(self):
+ def _return_cli(self) -> str:
"""The shell is the CLI."""
- return ''
+ return ""
- def disable_paging(self, *args, **kwargs):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
"""Linux doesn't have paging by default."""
return ""
- def set_base_prompt(self, pri_prompt_terminator='$',
- alt_prompt_terminator='#', delay_factor=1):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = LINUX_PROMPT_PRI,
+ alt_prompt_terminator: str = LINUX_PROMPT_ALT,
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Determine base prompt."""
- return super(LinuxSSH, self).set_base_prompt(
+ return super().set_base_prompt(
pri_prompt_terminator=pri_prompt_terminator,
alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
-
- def send_config_set(self, config_commands=None, exit_config_mode=True, **kwargs):
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = True,
+ **kwargs: Any,
+ ) -> str:
"""Can't exit from root (if root)"""
if self.username == "root":
exit_config_mode = False
- return super(LinuxSSH, self).send_config_set(config_commands=config_commands,
- exit_config_mode=exit_config_mode,
- **kwargs)
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
- def check_config_mode(self, check_string='#'):
+ def check_config_mode(
+ self, check_string: str = LINUX_PROMPT_ROOT, pattern: str = ""
+ ) -> bool:
"""Verify root"""
return self.check_enable_mode(check_string=check_string)
- def config_mode(self, config_command='sudo su'):
+ def config_mode(
+ self,
+ config_command: str = "sudo -s",
+ pattern: str = "ssword",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Attempt to become root."""
- return self.enable(cmd=config_command)
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
- def exit_config_mode(self, exit_config='exit'):
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "") -> str:
return self.exit_enable_mode(exit_command=exit_config)
- def check_enable_mode(self, check_string='#'):
+ def check_enable_mode(self, check_string: str = LINUX_PROMPT_ROOT) -> bool:
"""Verify root"""
- return super(LinuxSSH, self).check_enable_mode(check_string=check_string)
+ return super().check_enable_mode(check_string=check_string)
- def exit_enable_mode(self, exit_command='exit'):
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
"""Exit enable mode."""
delay_factor = self.select_delay_factor(delay_factor=0)
+ # You can run into a timing issue here if the time.sleep is too small
+ if delay_factor < 1:
+ delay_factor = 1
output = ""
if self.check_enable_mode():
self.write_channel(self.normalize_cmd(exit_command))
- time.sleep(.3 * delay_factor)
+ time.sleep(0.3 * delay_factor)
self.set_base_prompt()
if self.check_enable_mode():
raise ValueError("Failed to exit enable mode.")
return output
- def enable(self, cmd='sudo su', pattern='ssword', re_flags=re.IGNORECASE):
+ def enable(
+ self,
+ cmd: str = "sudo -s",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Attempt to become root."""
delay_factor = self.select_delay_factor(delay_factor=0)
output = ""
if not self.check_enable_mode():
self.write_channel(self.normalize_cmd(cmd))
- time.sleep(.3 * delay_factor)
+ time.sleep(0.3 * delay_factor)
try:
output += self.read_channel()
if re.search(pattern, output, flags=re_flags):
self.write_channel(self.normalize_cmd(self.secret))
self.set_base_prompt()
except socket.timeout:
- raise NetMikoTimeoutException("Timed-out reading channel, data not available.")
+ raise NetmikoTimeoutException(
+ "Timed-out reading channel, data not available."
+ )
if not self.check_enable_mode():
- msg = "Failed to enter enable mode. Please ensure you pass " \
- "the 'secret' argument to ConnectHandler."
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
raise ValueError(msg)
return output
- def cleanup(self):
+ def cleanup(self, command: str = "exit") -> None:
"""Try to Gracefully exit the SSH session."""
- self.write_channel("exit" + self.RETURN)
+ return super().cleanup(command=command)
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
"""Not Implemented"""
raise NotImplementedError
@@ -106,42 +144,62 @@ class LinuxFileTransfer(CiscoFileTransfer):
Mostly for testing purposes.
"""
- def __init__(self, ssh_conn, source_file, dest_file, file_system="/var/tmp", direction='put'):
- return super(LinuxFileTransfer, self).__init__(ssh_conn=ssh_conn,
- source_file=source_file,
- dest_file=dest_file,
- file_system=file_system,
- direction=direction)
-
- def remote_space_available(self, search_pattern=""):
+
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = "/var/tmp",
+ direction: str = "put",
+ **kwargs: Any,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ **kwargs,
+ )
+
+ def remote_space_available(self, search_pattern: str = "") -> int:
"""Return space available on remote device."""
return self._remote_space_available_unix(search_pattern=search_pattern)
- def check_file_exists(self, remote_cmd=""):
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
return self._check_file_exists_unix(remote_cmd=remote_cmd)
- def remote_file_size(self, remote_cmd="", remote_file=None):
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""Get the file size of the remote file."""
- return self._remote_file_size_unix(remote_cmd=remote_cmd, remote_file=remote_file)
+ return self._remote_file_size_unix(
+ remote_cmd=remote_cmd, remote_file=remote_file
+ )
- def remote_md5(self, base_cmd='md5sum', remote_file=None):
+ def remote_md5(
+ self, base_cmd: str = "md5sum", remote_file: Optional[str] = None
+ ) -> str:
if remote_file is None:
- if self.direction == 'put':
+ if self.direction == "put":
remote_file = self.dest_file
- elif self.direction == 'get':
+ elif self.direction == "get":
remote_file = self.source_file
- remote_md5_cmd = "{} {}/{}".format(base_cmd, self.file_system, remote_file)
- dest_md5 = self.ssh_ctl_chan.send_command(remote_md5_cmd, max_loops=750, delay_factor=2)
- dest_md5 = self.process_md5(dest_md5)
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
+ dest_md5 = self.process_md5(dest_md5).strip()
return dest_md5
@staticmethod
- def process_md5(md5_output, pattern=r"^(\S+)\s+"):
- return super(LinuxFileTransfer, LinuxFileTransfer).process_md5(md5_output, pattern=pattern)
+ def process_md5(md5_output: str, pattern: str = r"^(\S+)\s+") -> str:
+ return super(LinuxFileTransfer, LinuxFileTransfer).process_md5(
+ md5_output, pattern=pattern
+ )
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "") -> None:
raise NotImplementedError
diff --git a/netmiko/mellanox/__init__.py b/netmiko/mellanox/__init__.py
index 2df6bbc95..33c695273 100644
--- a/netmiko/mellanox/__init__.py
+++ b/netmiko/mellanox/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
-from netmiko.mellanox.mellanox_ssh import MellanoxSSH
+from netmiko.mellanox.mellanox_mlnxos_ssh import MellanoxMlnxosSSH
-__all__ = ['MellanoxSSH']
+__all__ = ["MellanoxMlnxosSSH"]
diff --git a/netmiko/mellanox/mellanox_mlnxos_ssh.py b/netmiko/mellanox/mellanox_mlnxos_ssh.py
new file mode 100644
index 000000000..f4f5c1d13
--- /dev/null
+++ b/netmiko/mellanox/mellanox_mlnxos_ssh.py
@@ -0,0 +1,92 @@
+"""Mellanox MLNX-OS Switch support."""
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko import log
+
+
+class MellanoxMlnxosSSH(CiscoSSHConnection):
+ """Mellanox MLNX-OS Switch support."""
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter into enable mode."""
+ output = ""
+ if not self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(cmd))
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ if not self.check_enable_mode():
+ raise ValueError("Failed to enter enable mode.")
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config term",
+ pattern: str = r"\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def disable_paging(
+ self,
+ command: str = "no cli session paging enable",
+ delay_factor: Optional[float] = None,
+ cmd_verify: bool = True,
+ pattern: Optional[str] = None,
+ ) -> str:
+ return super().disable_paging(
+ command=command,
+ delay_factor=delay_factor,
+ cmd_verify=cmd_verify,
+ pattern=pattern,
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ """Mellanox does not support a single command to completely exit configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ # One last check for whether we successfully exited config mode
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+
+ log.debug(f"exit_config_mode: {output}")
+ return output
+
+ def save_config(
+ self,
+ cmd: str = "configuration write",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Save Config on Mellanox devices Enters and Leaves Config Mode"""
+ output = self.enable()
+ output += self.config_mode()
+ output += self._send_command_str(cmd)
+ output += self.exit_config_mode()
+ return output
diff --git a/netmiko/mellanox/mellanox_ssh.py b/netmiko/mellanox/mellanox_ssh.py
deleted file mode 100644
index 3f9aa5f59..000000000
--- a/netmiko/mellanox/mellanox_ssh.py
+++ /dev/null
@@ -1,58 +0,0 @@
-
-from __future__ import unicode_literals
-from netmiko.cisco_base_connection import CiscoSSHConnection
-from netmiko import log
-import time
-
-
-class MellanoxSSH(CiscoSSHConnection):
-
- def config_mode(self, config_command='config term', pattern='#'):
- """Enter into config_mode."""
- output = ''
- if not self.check_config_mode():
- self.write_channel(self.normalize_cmd(config_command))
- output = self.read_until_pattern(pattern=pattern)
- if not self.check_config_mode():
- raise ValueError("Failed to enter configuration mode.")
- return output
-
- def check_config_mode(self, check_string='(config)', pattern=r'[>|#]'):
- return super(MellanoxSSH, self).check_config_mode(check_string=check_string,
- pattern=pattern)
-
- def disable_paging(self, command="terminal length 999", delay_factor=1):
- """Disable paging default to a Cisco CLI method."""
- delay_factor = self.select_delay_factor(delay_factor)
- time.sleep(delay_factor * .1)
- self.clear_buffer()
- command = self.normalize_cmd(command)
- log.debug("In disable_paging")
- log.debug("Command: {0}".format(command))
- self.write_channel(command)
- output = self.read_until_prompt()
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- log.debug("{0}".format(output))
- log.debug("Exiting disable_paging")
- return output
-
- def exit_config_mode(self, exit_config='exit', pattern='#'):
- """Exit from configuration mode."""
- output = ''
- if self.check_config_mode():
- self.write_channel(self.normalize_cmd(exit_config))
- output = self.read_until_pattern(pattern=pattern)
- if self.check_config_mode():
- raise ValueError("Failed to exit configuration mode")
- log.debug("exit_config_mode: {0}".format(output))
- return output
-
- def save_config(self, cmd='configuration write', confirm=False,
- confirm_response=''):
- """Save Config on Mellanox devices Enters and Leaves Config Mode"""
- output = self.enable()
- output += self.config_mode()
- output += self.send_command(cmd)
- output += self.exit_config_mode()
- return output
diff --git a/netmiko/mikrotik/README.md b/netmiko/mikrotik/README.md
new file mode 100644
index 000000000..f6739a944
--- /dev/null
+++ b/netmiko/mikrotik/README.md
@@ -0,0 +1,23 @@
+MicroTik RouterOS and SwitchOS support
+
+This module is provided under The MIT License (MIT)
+
+Copyright (c) 2019 Darcy Buskermolen darcy@dbitech.ca
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/netmiko/mikrotik/__init__.py b/netmiko/mikrotik/__init__.py
new file mode 100644
index 000000000..11eb945ca
--- /dev/null
+++ b/netmiko/mikrotik/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.mikrotik.mikrotik_ssh import MikrotikRouterOsSSH
+from netmiko.mikrotik.mikrotik_ssh import MikrotikSwitchOsSSH
+
+__all__ = ["MikrotikRouterOsSSH", "MikrotikSwitchOsSSH"]
diff --git a/netmiko/mikrotik/mikrotik_ssh.py b/netmiko/mikrotik/mikrotik_ssh.py
new file mode 100644
index 000000000..203c31906
--- /dev/null
+++ b/netmiko/mikrotik/mikrotik_ssh.py
@@ -0,0 +1,119 @@
+from typing import Any, Union, List, Dict, Optional
+from netmiko.no_enable import NoEnable
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class MikrotikBase(NoEnable, CiscoSSHConnection):
+ """Common Methods for Mikrotik RouterOS and SwitchOS"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+
+ self._in_config_mode = False
+
+ return super().__init__(**kwargs)
+
+ def session_preparation(self, *args: Any, **kwargs: Any) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"\].*>")
+ self.set_base_prompt()
+
+ def _modify_connection_params(self) -> None:
+ """Append login options to username
+ c: disable console colors
+ e: enable dumb terminal mode
+ t: disable auto detect terminal capabilities
+ w511: set term width
+ h4098: set term height
+ """
+ self.username += "+ctw511h4098"
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """Mikrotik does not have paging by default."""
+ return ""
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save command, all configuration is atomic"""
+ return ""
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = True
+ return ""
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+ return self._in_config_mode
+
+ def exit_config_mode(self, exit_config: str = ">", pattern: str = "") -> str:
+ """No configuration mode on Mikrotik"""
+ self._in_config_mode = False
+ return ""
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output.
+
+ Mikrotik just does a lot of formatting/has ansi escape codes in output so
+ we need a special handler here.
+
+ There can be two trailing instances of the prompt probably due to
+ repainting.
+ """
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ # Drop the first trailing prompt
+ if self.base_prompt in last_line:
+ a_string = self.RESPONSE_RETURN.join(response_list[:-1])
+ a_string = a_string.rstrip()
+ # Now it should be just normal: call the parent method
+ a_string = super().strip_prompt(a_string)
+ return a_string.strip()
+ else:
+ # Unexpected just return the original string
+ return a_string
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = ">",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Strip the trailing space off."""
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def send_command_timing( # type: ignore
+ self,
+ command_string: str,
+ cmd_verify: bool = True,
+ **kwargs: Any,
+ ) -> Union[str, List[Any], Dict[str, Any]]:
+ """Force cmd_verify to be True due to all of the line repainting"""
+ return super()._send_command_timing_str(
+ command_string=command_string, cmd_verify=cmd_verify, **kwargs
+ )
+
+
+class MikrotikRouterOsSSH(MikrotikBase):
+ """Mikrotik RouterOS SSH driver."""
+
+ pass
+
+
+class MikrotikSwitchOsSSH(MikrotikBase):
+ """Mikrotik SwitchOS SSH driver."""
+
+ pass
diff --git a/netmiko/mrv/__init__.py b/netmiko/mrv/__init__.py
index 90b8f3038..8bd3f2901 100644
--- a/netmiko/mrv/__init__.py
+++ b/netmiko/mrv/__init__.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from netmiko.mrv.mrv_lx import MrvLxSSH
from netmiko.mrv.mrv_ssh import MrvOptiswitchSSH
-__all__ = ['MrvOptiswitchSSH']
+__all__ = ["MrvOptiswitchSSH", "MrvLxSSH"]
diff --git a/netmiko/mrv/mrv_lx.py b/netmiko/mrv/mrv_lx.py
new file mode 100644
index 000000000..c25add6fe
--- /dev/null
+++ b/netmiko/mrv/mrv_lx.py
@@ -0,0 +1,45 @@
+"""MRV Communications Driver (LX)."""
+import time
+import re
+from typing import Optional
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class MrvLxSSH(CiscoSSHConnection):
+ """MRV Communications Driver (LX)."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>|>>]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="no pause")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = ">>") -> bool:
+ """MRV has a >> for enable mode instead of # like Cisco"""
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = "assword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """Enter enable mode."""
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves configuration."""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/mrv/mrv_ssh.py b/netmiko/mrv/mrv_ssh.py
index dddbe7412..57ad056ac 100644
--- a/netmiko/mrv/mrv_ssh.py
+++ b/netmiko/mrv/mrv_ssh.py
@@ -1,35 +1,54 @@
"""MRV Communications Driver (OptiSwitch)."""
-from __future__ import unicode_literals
import time
import re
+from typing import Optional
from netmiko.cisco_base_connection import CiscoSSHConnection
class MrvOptiswitchSSH(CiscoSSHConnection):
"""MRV Communications Driver (OptiSwitch)."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
- self._test_channel_read(pattern=r'[>#]')
- self.enable()
+ self._test_channel_read(pattern=r"[>#]")
self.set_base_prompt()
+ self.enable()
self.disable_paging(command="no cli-paging")
# Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
+ time.sleep(0.3 * self.global_delay_factor)
+ self.set_base_prompt()
self.clear_buffer()
- def enable(self, cmd='enable', pattern=r'#', re_flags=re.IGNORECASE):
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"#",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Enable mode on MRV uses no password."""
output = ""
if not self.check_enable_mode():
self.write_channel(self.normalize_cmd(cmd))
- output += self.read_until_prompt_or_pattern(pattern=pattern, re_flags=re_flags)
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
if not self.check_enable_mode():
- msg = "Failed to enter enable mode. Please ensure you pass " \
- "the 'secret' argument to ConnectHandler."
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
raise ValueError(msg)
return output
- def save_config(self, cmd='save config flash', confirm=False):
+ def save_config(
+ self,
+ cmd: str = "save config flash",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Saves configuration."""
- return super(MrvOptiswitchSSH, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/netapp/__init__.py b/netmiko/netapp/__init__.py
index ea0eeb2a7..23d5259fd 100644
--- a/netmiko/netapp/__init__.py
+++ b/netmiko/netapp/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.netapp.netapp_cdot_ssh import NetAppcDotSSH
-__all__ = ['NetAppcDotSSH']
+__all__ = ["NetAppcDotSSH"]
diff --git a/netmiko/netapp/netapp_cdot_ssh.py b/netmiko/netapp/netapp_cdot_ssh.py
index 6415ff1c1..9fc15e63f 100644
--- a/netmiko/netapp/netapp_cdot_ssh.py
+++ b/netmiko/netapp/netapp_cdot_ssh.py
@@ -1,38 +1,40 @@
-from __future__ import unicode_literals
+from typing import Any
+from netmiko.no_enable import NoEnable
from netmiko.base_connection import BaseConnection
-class NetAppcDotSSH(BaseConnection):
-
- def session_preparation(self):
+class NetAppcDotSSH(NoEnable, BaseConnection):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self.set_base_prompt()
cmd = self.RETURN + "rows 0" + self.RETURN
self.disable_paging(command=cmd)
- def send_command_with_y(self, *args, **kwargs):
- output = self.send_command_timing(*args, **kwargs)
- if '{y|n}' in output:
- output += self.send_command_timing('y', strip_prompt=False,
- strip_command=False)
+ def send_command_with_y(self, *args: Any, **kwargs: Any) -> str:
+ output = self._send_command_timing_str(*args, **kwargs)
+ if "{y|n}" in output:
+ output += self._send_command_timing_str(
+ "y", strip_prompt=False, strip_command=False
+ )
return output
- def check_config_mode(self, check_string='*>'):
- return super(NetAppcDotSSH, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='set -privilege diagnostic -confirmations off'):
- return super(NetAppcDotSSH, self).config_mode(config_command=config_command)
-
- def exit_config_mode(self, exit_config='set -privilege admin -confirmations off'):
- return super(NetAppcDotSSH, self).exit_config_mode(exit_config=exit_config)
-
- def enable(self, *args, **kwargs):
- """No enable mode on NetApp."""
- pass
-
- def check_enable_mode(self, *args, **kwargs):
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- pass
+ def check_config_mode(self, check_string: str = "*>", pattern: str = "") -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "set -privilege diagnostic -confirmations off",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self,
+ exit_config: str = "set -privilege admin -confirmations off",
+ pattern: str = "",
+ ) -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
diff --git a/netmiko/netgear/__init__.py b/netmiko/netgear/__init__.py
new file mode 100644
index 000000000..e1a1cd1f1
--- /dev/null
+++ b/netmiko/netgear/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.netgear.netgear_prosafe_ssh import NetgearProSafeSSH
+
+__all__ = ["NetgearProSafeSSH"]
diff --git a/netmiko/netgear/netgear_prosafe_ssh.py b/netmiko/netgear/netgear_prosafe_ssh.py
new file mode 100644
index 000000000..3d7285b8b
--- /dev/null
+++ b/netmiko/netgear/netgear_prosafe_ssh.py
@@ -0,0 +1,58 @@
+"""ProSafe OS support"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class NetgearProSafeSSH(CiscoSSHConnection):
+ """ProSafe OS support"""
+
+ def __init__(self, **kwargs: Any) -> None:
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """ProSafe OS requires enable mode to disable paging."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="terminal length 0")
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(
+ self, check_string: str = "(Config)#", pattern: str = ""
+ ) -> bool:
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\)\#",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"\#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(
+ self,
+ save_cmd: str = "write memory confirm",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ self.enable()
+ """ProSafe doesn't allow saving whilst within configuration mode"""
+ if self.check_config_mode():
+ self.exit_config_mode()
+
+ return super().save_config(
+ cmd=save_cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/netmiko_globals.py b/netmiko/netmiko_globals.py
index a0eaa303b..bb021314f 100644
--- a/netmiko/netmiko_globals.py
+++ b/netmiko/netmiko_globals.py
@@ -1,4 +1,2 @@
-from __future__ import unicode_literals
-
MAX_BUFFER = 65535
-BACKSPACE_CHAR = '\x08'
+BACKSPACE_CHAR = "\x08"
diff --git a/netmiko/no_config.py b/netmiko/no_config.py
new file mode 100644
index 000000000..d6718054b
--- /dev/null
+++ b/netmiko/no_config.py
@@ -0,0 +1,22 @@
+class NoConfig:
+ """
+ Class for platforms that have no config mode.
+
+ check_config_mode returns True as the expectation is that configuration commands
+ can be executed directly. So in your current state, you are in "config mode" i.e.
+ you can make configuration changes.
+
+ If you truly cannot make any configuration changes to device then you should probably
+ overwrite check_config_mode in the platform specific driver and return False.
+ """
+
+ def check_config_mode(self, check_string: str = "", pattern: str = "") -> bool:
+ return True
+
+ def config_mode(
+ self, config_command: str = "", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return ""
+
+ def exit_config_mode(self, exit_config: str = "", pattern: str = "") -> str:
+ return ""
diff --git a/netmiko/no_enable.py b/netmiko/no_enable.py
new file mode 100644
index 000000000..aa8399bbd
--- /dev/null
+++ b/netmiko/no_enable.py
@@ -0,0 +1,33 @@
+from typing import Optional
+import re
+
+
+class NoEnable:
+ """
+ Class for platforms that have no enable mode.
+
+ Netmiko translates the meaning of "enable" mode to be a proxy for "can
+ go into config mode". In other words, that you ultimately have privileges
+ to execute configuration changes.
+
+ The expectation on platforms that have no method for elevating privileges
+ is that the standard default privileges allow configuration changes.
+
+ Consequently check_enable_mode returns True by default for platforms that
+ don't explicitly support enable mode.
+ """
+
+ def check_enable_mode(self, check_string: str = "") -> bool:
+ return True
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return ""
+
+ def exit_enable_mode(self, exit_command: str = "") -> str:
+ return ""
diff --git a/netmiko/nokia/__init__.py b/netmiko/nokia/__init__.py
new file mode 100755
index 000000000..41f573d2d
--- /dev/null
+++ b/netmiko/nokia/__init__.py
@@ -0,0 +1,7 @@
+from netmiko.nokia.nokia_sros import (
+ NokiaSrosSSH,
+ NokiaSrosTelnet,
+ NokiaSrosFileTransfer,
+)
+
+__all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer", "NokiaSrosTelnet"]
diff --git a/netmiko/nokia/nokia_sros.py b/netmiko/nokia/nokia_sros.py
new file mode 100644
index 000000000..dcd82b12b
--- /dev/null
+++ b/netmiko/nokia/nokia_sros.py
@@ -0,0 +1,386 @@
+#!/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 typing import Any, Optional, Union, Sequence, TextIO, Callable
+
+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) -> None:
+ 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: Any, **kwargs: Any) -> str:
+ """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: str = match.group(1)
+
+ return self.base_prompt
+
+ def _disable_complete_on_space(self) -> str:
+ """
+ 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: str = "enable",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """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: str = "in admin mode") -> bool:
+ """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", read_entire_line=True
+ )
+ if "ssword" in output:
+ self.write_channel(self.RETURN) # send ENTER to pass the password prompt
+ self.read_until_prompt(read_entire_line=True)
+ return check_string in output
+
+ def exit_enable_mode(self, *args: Any, **kwargs: Any) -> str:
+ """Nokia SR OS does not have a notion of exiting administrative mode"""
+ return ""
+
+ def config_mode(
+ self,
+ config_command: str = "edit-config exclusive",
+ pattern: str = "",
+ re_flags: int = 0,
+ ) -> str:
+ """Enable config edit-mode for Nokia SR OS"""
+ output = ""
+ if not pattern:
+ pattern = rf"\(ex\)\[.*{self.base_prompt}.*$"
+ re_flags = re.DOTALL
+ # Only model-driven CLI supports config-mode
+ if "@" in self.base_prompt:
+ output += super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+ return output
+
+ def exit_config_mode(self, *args: Any, **kwargs: Any) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ return output
+
+ def check_config_mode(
+ self, check_string: str = r"(ex)[", pattern: str = r"@"
+ ) -> bool:
+ """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: Any, **kwargs: Any) -> str:
+ """Persist configuration to cflash for Nokia SR OS"""
+ return self._send_command_str(command_string="/admin save", expect_string=r"#")
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = None,
+ **kwargs: Any,
+ ) -> str:
+ """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: Any, **kwargs: Any) -> str:
+ """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) -> str:
+ """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))
+ output += self.read_until_prompt(read_entire_line=True)
+ else:
+ output += self.read_until_prompt(read_entire_line=True)
+ return output
+
+ def _discard(self) -> str:
+ """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(read_entire_line=True)
+ output += new_output
+ return output
+
+ def strip_prompt(self, *args: Any, **kwargs: Any) -> str:
+ """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: str = "logout") -> None:
+ """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: BaseConnection,
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = False,
+ ) -> None:
+ super().__init__(
+ ssh_conn=ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ socket_timeout=socket_timeout,
+ progress=progress,
+ progress4=progress4,
+ hash_supported=hash_supported,
+ )
+
+ def _file_cmd_prefix(self) -> str:
+ """
+ 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: str = r"(\d+)\s+\w+\s+free"
+ ) -> int:
+ """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_str(remote_cmd)
+ match = re.search(search_pattern, remote_output)
+ assert match is not None
+ return int(match.group(1))
+
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
+ """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)
+ else:
+ raise ValueError("Unexpected value for self.direction")
+
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
+ """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
+ else:
+ raise ValueError("Unexpected value for self.direction")
+ 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_str(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) -> bool:
+ """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
+ )
+ else:
+ raise ValueError("Unexpected value of self.direction")
+
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ @staticmethod
+ def process_md5(md5_output: str, pattern: str = "") -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def compare_md5(self) -> bool:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
+
+ def remote_md5(self, base_cmd: str = "", remote_file: Optional[str] = None) -> str:
+ raise AttributeError("SR-OS does not support an MD5-hash operation.")
diff --git a/netmiko/oneaccess/__init__.py b/netmiko/oneaccess/__init__.py
new file mode 100644
index 000000000..a3d597813
--- /dev/null
+++ b/netmiko/oneaccess/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.oneaccess.oneaccess_oneos import OneaccessOneOSSSH, OneaccessOneOSTelnet
+
+__all__ = ["OneaccessOneOSSSH", "OneaccessOneOSTelnet"]
diff --git a/netmiko/oneaccess/oneaccess_oneos.py b/netmiko/oneaccess/oneaccess_oneos.py
new file mode 100644
index 000000000..8e902888d
--- /dev/null
+++ b/netmiko/oneaccess/oneaccess_oneos.py
@@ -0,0 +1,39 @@
+"""Netmiko driver for OneAccess ONEOS"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class OneaccessOneOSBase(CiscoBaseConnection):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ """Init connection - similar as Cisco"""
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def session_preparation(self) -> None:
+ """Prepare connection - disable paging"""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="stty columns 255", pattern="stty")
+ self.disable_paging(command="term len 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write mem"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class OneaccessOneOSSSH(OneaccessOneOSBase):
+ pass
+
+
+class OneaccessOneOSTelnet(OneaccessOneOSBase):
+ pass
diff --git a/netmiko/ovs/__init__.py b/netmiko/ovs/__init__.py
index 9837fad7c..0177060af 100644
--- a/netmiko/ovs/__init__.py
+++ b/netmiko/ovs/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.ovs.ovs_linux_ssh import OvsLinuxSSH
-__all__ = ['OvsLinuxSSH']
+__all__ = ["OvsLinuxSSH"]
diff --git a/netmiko/ovs/ovs_linux_ssh.py b/netmiko/ovs/ovs_linux_ssh.py
index efd76d20d..847f66ab9 100644
--- a/netmiko/ovs/ovs_linux_ssh.py
+++ b/netmiko/ovs/ovs_linux_ssh.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.linux.linux_ssh import LinuxSSH
diff --git a/netmiko/paloalto/__init__.py b/netmiko/paloalto/__init__.py
index f34f9fdfa..50d005bf0 100644
--- a/netmiko/paloalto/__init__.py
+++ b/netmiko/paloalto/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
-from netmiko.paloalto.paloalto_panos_ssh import PaloAltoPanosSSH
+from netmiko.paloalto.paloalto_panos import PaloAltoPanosSSH, PaloAltoPanosTelnet
-__all__ = ['PaloAltoPanosSSH']
+__all__ = ["PaloAltoPanosSSH", "PaloAltoPanosTelnet"]
diff --git a/netmiko/paloalto/paloalto_panos.py b/netmiko/paloalto/paloalto_panos.py
new file mode 100644
index 000000000..99adf98af
--- /dev/null
+++ b/netmiko/paloalto/paloalto_panos.py
@@ -0,0 +1,252 @@
+from typing import Optional, List, Any, Tuple
+import re
+import warnings
+from os import path
+from paramiko import SSHClient, Transport
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection, DELAY_FACTOR_DEPR_SIMPLE_MSG
+
+
+class SSHClient_interactive(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def pa_banner_handler(
+ self, title: str, instructions: str, prompt_list: List[Tuple[str, bool]]
+ ) -> List[str]:
+
+ resp = []
+ for prompt, echo in prompt_list:
+ if "Do you accept" in prompt:
+ resp.append("yes")
+ elif "ssword" in prompt:
+ assert isinstance(self.password, str)
+ resp.append(self.password)
+ return resp
+
+ def _auth(self, username: str, password: str, *args: Any) -> None:
+ """
+ _auth: args as of aug-2021
+ self,
+ username,
+ password,
+ pkey,
+ key_filenames,
+ allow_agent,
+ look_for_keys,
+ gss_auth,
+ gss_kex,
+ gss_deleg_creds,
+ gss_host,
+ passphrase,
+ """
+
+ # Just gets the password up to the pa_banner_handler
+ self.password = password
+ transport = self.get_transport()
+ assert isinstance(transport, Transport)
+ transport.auth_interactive(username, handler=self.pa_banner_handler)
+ return
+
+
+class PaloAltoPanosBase(NoEnable, BaseConnection):
+ """
+ Implement methods for interacting with PaloAlto devices.
+
+ Disables `enable()` and `check_enable_mode()`
+ methods. Overrides several methods for PaloAlto-specific compatibility.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Disable paging (the '--more--' prompts).
+ Set the base prompt for interaction ('>').
+ """
+ self.ansi_escape_codes = True
+ self._test_channel_read(pattern=r"[>#]")
+ self.disable_paging(
+ command="set cli scripting-mode on", cmd_verify=False, pattern=r" on"
+ )
+ self.set_terminal_width(
+ command="set cli terminal width 500", pattern=r"set cli terminal width 500"
+ )
+ self.disable_paging(command="set cli pager off")
+ self.set_base_prompt()
+
+ # PA devices can be really slow--try to make sure we are caught up
+ self.write_channel("show admins\n")
+ self._test_channel_read(pattern=r"Client")
+ self._test_channel_read(pattern=r"[>#]")
+
+ def find_prompt(
+ self, delay_factor: float = 5.0, pattern: Optional[str] = None
+ ) -> str:
+ """PA devices can be very slow to respond (in certain situations)"""
+ return super().find_prompt(delay_factor=delay_factor, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "]", pattern: str = "") -> bool:
+ """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: str = "configure", pattern: str = r"#", re_flags: int = 0
+ ) -> str:
+ """Enter configuration mode."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def commit(
+ self,
+ comment: str = "",
+ force: bool = False,
+ partial: bool = False,
+ device_and_network: bool = False,
+ policy_and_objects: bool = False,
+ vsys: str = "",
+ no_vsys: bool = False,
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Commit the entered configuration. Raise an error and return the failure
+ if the commit fails.
+
+ Automatically enters configuration mode
+
+ default:
+ command_string = commit
+ (device_and_network or policy_and_objects or vsys or
+ no_vsys) and not partial:
+ Exception
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ if (
+ device_and_network or policy_and_objects or vsys or no_vsys
+ ) and not partial:
+ raise ValueError(
+ "'partial' must be True when using "
+ "device_and_network or policy_and_objects "
+ "or vsys or no_vsys."
+ )
+
+ # Select proper command string based on arguments provided
+ command_string = "commit"
+ commit_marker = "configuration committed successfully"
+ if comment:
+ command_string += f' description "{comment}"'
+ if force:
+ command_string += " force"
+ if partial:
+ command_string += " partial"
+ if vsys:
+ command_string += f" {vsys}"
+ if device_and_network:
+ command_string += " device-and-network"
+ if policy_and_objects:
+ command_string += " device-and-network"
+ if no_vsys:
+ command_string += " no-vsys"
+ command_string += " excluded"
+
+ # Enter config mode (if necessary)
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ expect_string="100%",
+ read_timeout=read_timeout,
+ )
+ output += self.exit_config_mode()
+
+ if commit_marker not in output.lower():
+ raise ValueError(f"Commit failed with the following errors:\n\n{output}")
+ return output
+
+ def strip_command(self, command_string: str, output: str) -> str:
+ """Strip command_string from output string."""
+ output_list = output.split(command_string)
+ return self.RESPONSE_RETURN.join(output_list)
+
+ def strip_prompt(self, a_string: str) -> str:
+ """Strip the trailing router prompt from the output."""
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ new_response_list = []
+ for line in response_list:
+ if self.base_prompt not in line:
+ new_response_list.append(line)
+
+ output = self.RESPONSE_RETURN.join(new_response_list)
+ return self.strip_context_items(output)
+
+ def strip_context_items(self, a_string: str) -> str:
+ """Strip PaloAlto-specific output.
+
+ PaloAlto will also put a configuration context:
+ [edit]
+
+ This method removes those lines.
+ """
+ strings_to_strip = [r"\[edit.*\]"]
+
+ response_list = a_string.split(self.RESPONSE_RETURN)
+ last_line = response_list[-1]
+
+ for pattern in strings_to_strip:
+ if re.search(pattern, last_line):
+ return self.RESPONSE_RETURN.join(response_list[:-1])
+
+ return a_string
+
+ def cleanup(self, command: str = "exit") -> None:
+ """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 'exit' (command)
+ self._session_log_fin = True
+ self.write_channel(command + self.RETURN)
+
+
+class PaloAltoPanosSSH(PaloAltoPanosBase):
+ def _build_ssh_client(self) -> SSHClient:
+ """Prepare for Paramiko SSH connection."""
+ # Create instance of SSHClient object
+ # If not using SSH keys, we use noauth
+
+ if not self.use_keys:
+ remote_conn_pre: SSHClient = SSHClient_interactive()
+ else:
+ remote_conn_pre = SSHClient()
+
+ # Load host_keys for better SSH security
+ if self.system_host_keys:
+ remote_conn_pre.load_system_host_keys()
+ if self.alt_host_keys and path.isfile(self.alt_key_file):
+ remote_conn_pre.load_host_keys(self.alt_key_file)
+
+ # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+ remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+ return remote_conn_pre
+
+
+class PaloAltoPanosTelnet(PaloAltoPanosBase):
+ pass
diff --git a/netmiko/paloalto/paloalto_panos_ssh.py b/netmiko/paloalto/paloalto_panos_ssh.py
deleted file mode 100644
index 8dc0b07e2..000000000
--- a/netmiko/paloalto/paloalto_panos_ssh.py
+++ /dev/null
@@ -1,149 +0,0 @@
-from __future__ import unicode_literals
-import time
-import re
-from netmiko.base_connection import BaseConnection
-
-
-class PaloAltoPanosSSH(BaseConnection):
- """
- Implement methods for interacting with PaloAlto devices.
-
- Disables `enable()` and `check_enable_mode()`
- methods. Overrides several methods for PaloAlto-specific compatibility.
- """
- 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()
- self.set_base_prompt(delay_factor=20)
- self.disable_paging(command="set cli pager off")
- # Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
- self.clear_buffer()
-
- def check_enable_mode(self, *args, **kwargs):
- """No enable mode on PaloAlto."""
- pass
-
- def enable(self, *args, **kwargs):
- """No enable mode on PaloAlto."""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on PaloAlto."""
- pass
-
- def check_config_mode(self, check_string=']'):
- """Checks if the device is in configuration mode or not."""
- return super(PaloAltoPanosSSH, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='configure'):
- """Enter configuration mode."""
- return super(PaloAltoPanosSSH, self).config_mode(config_command=config_command)
-
- def exit_config_mode(self, exit_config='exit', pattern=r'>'):
- """Exit configuration mode."""
- return super(PaloAltoPanosSSH, self).exit_config_mode(exit_config=exit_config,
- pattern=pattern)
-
- def commit(self, force=False, partial=False, device_and_network=False,
- policy_and_objects=False, vsys='', no_vsys=False, 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
-
- default:
- command_string = commit
- (device_and_network or policy_and_objects or vsys or
- no_vsys) and not partial:
- Exception
- """
- delay_factor = self.select_delay_factor(delay_factor)
-
- if ((device_and_network or policy_and_objects or vsys or
- no_vsys) and not partial):
- raise ValueError("'partial' must be True when using "
- "device_and_network or policy_and_objects "
- "or vsys or no_vsys.")
-
- # Select proper command string based on arguments provided
- command_string = 'commit'
- commit_marker = 'configuration committed successfully'
- if force:
- command_string += ' force'
- if partial:
- command_string += ' partial'
- if vsys:
- command_string += ' {0}'.format(vsys)
- if device_and_network:
- command_string += ' device-and-network'
- if policy_and_objects:
- command_string += ' device-and-network'
- if no_vsys:
- command_string += ' no-vsys'
- command_string += ' excluded'
-
- # Enter config mode (if necessary)
- output = self.config_mode()
- output += self.send_command_expect(command_string, strip_prompt=False,
- strip_command=False, expect_string='100%',
- delay_factor=delay_factor)
-
- if commit_marker not in output.lower():
- raise ValueError("Commit failed with the following errors:\n\n{0}"
- .format(output))
- return output
-
- def strip_command(self, command_string, output):
- """Strip command_string from output string."""
- output_list = output.split(command_string)
- return self.RESPONSE_RETURN.join(output_list)
-
- def strip_prompt(self, a_string):
- """Strip the trailing router prompt from the output."""
- response_list = a_string.split(self.RESPONSE_RETURN)
- new_response_list = []
- for line in response_list:
- if self.base_prompt not in line:
- new_response_list.append(line)
-
- output = self.RESPONSE_RETURN.join(new_response_list)
- return self.strip_context_items(output)
-
- def strip_context_items(self, a_string):
- """Strip PaloAlto-specific output.
-
- PaloAlto will also put a configuration context:
- [edit]
-
- This method removes those lines.
- """
- strings_to_strip = [
- r'\[edit.*\]',
- ]
-
- response_list = a_string.split(self.RESPONSE_RETURN)
- last_line = response_list[-1]
-
- for pattern in strings_to_strip:
- if re.search(pattern, last_line):
- return self.RESPONSE_RETURN.join(response_list[:-1])
-
- return a_string
-
- def send_command_expect(self, *args, **kwargs):
- """Palo Alto requires an extra delay"""
- return self.send_command(*args, **kwargs)
-
- def send_command(self, *args, **kwargs):
- """Palo Alto requires an extra delay"""
- kwargs['delay_factor'] = kwargs.get('delay_factor', 2.5)
- return super(PaloAltoPanosSSH, self).send_command(*args, **kwargs)
diff --git a/netmiko/pluribus/__init__.py b/netmiko/pluribus/__init__.py
index b4f00d668..2e2bcb329 100644
--- a/netmiko/pluribus/__init__.py
+++ b/netmiko/pluribus/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
from netmiko.pluribus.pluribus_ssh import PluribusSSH
-__all__ = ('PluribusSSH',)
+__all__ = ("PluribusSSH",)
diff --git a/netmiko/pluribus/pluribus_ssh.py b/netmiko/pluribus/pluribus_ssh.py
index fed5fdce5..2200e804f 100644
--- a/netmiko/pluribus/pluribus_ssh.py
+++ b/netmiko/pluribus/pluribus_ssh.py
@@ -1,41 +1,22 @@
-from __future__ import unicode_literals
import time
+from typing import Any
+
+from netmiko.no_config import NoConfig
from netmiko.base_connection import BaseConnection
-class PluribusSSH(BaseConnection):
- '''Common methods for Pluribus.'''
+class PluribusSSH(NoConfig, BaseConnection):
+ """Common methods for Pluribus."""
- def __init__(self, *args, **kwargs):
- super(PluribusSSH, self).__init__(*args, **kwargs)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ super().__init__(*args, **kwargs)
self._config_mode = False
- def disable_paging(self, command="pager off", delay_factor=1):
- '''Make sure paging is disabled.'''
- return super(PluribusSSH, self).disable_paging(command=command, delay_factor=delay_factor)
-
- def session_preparation(self):
- '''Prepare the netmiko session.'''
+ def session_preparation(self) -> None:
+ """Prepare the netmiko session."""
self._test_channel_read()
self.set_base_prompt()
self.disable_paging()
# Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
+ time.sleep(0.3 * self.global_delay_factor)
self.clear_buffer()
-
- def check_config_mode(self, *args, **kwargs):
- '''
- Pluribus devices don't have a config mode.
- Therefore it can be considered as always in config mode.
- '''
- return self._config_mode
-
- def config_mode(self, *args, **kwargs):
- '''No special actions to enter in config mode.'''
- self._config_mode = True
- return ''
-
- def exit_config_mode(self, *args, **kwargs):
- '''No special actions to exit config mode.'''
- self._config_mode = False
- return ''
diff --git a/netmiko/py23_compat.py b/netmiko/py23_compat.py
deleted file mode 100644
index 90c37da57..000000000
--- a/netmiko/py23_compat.py
+++ /dev/null
@@ -1,18 +0,0 @@
-"""Simplify Python3 compatibility. Modeled after six behavior for small set of things"""
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import io
-import sys
-
-PY2 = sys.version_info.major == 2
-PY3 = sys.version_info.major == 3
-
-if PY3:
- string_types = (str,)
- text_type = str
- bytes_io_types = io.BufferedIOBase
-else:
- string_types = (basestring,) # noqa
- text_type = unicode # noqa
- bytes_io_types = (io.BufferedIOBase, file) # noqa
diff --git a/netmiko/quanta/__init__.py b/netmiko/quanta/__init__.py
index d8a8c0ceb..3e26d6f0b 100644
--- a/netmiko/quanta/__init__.py
+++ b/netmiko/quanta/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.quanta.quanta_mesh_ssh import QuantaMeshSSH
-__all__ = ['QuantaMeshSSH']
+__all__ = ["QuantaMeshSSH"]
diff --git a/netmiko/quanta/quanta_mesh_ssh.py b/netmiko/quanta/quanta_mesh_ssh.py
index ddca0961e..69302512a 100644
--- a/netmiko/quanta/quanta_mesh_ssh.py
+++ b/netmiko/quanta/quanta_mesh_ssh.py
@@ -1,16 +1,27 @@
-from __future__ import unicode_literals
from netmiko.cisco_base_connection import CiscoSSHConnection
class QuantaMeshSSH(CiscoSSHConnection):
- def disable_paging(self, command="no pager", delay_factor=1):
- """Disable paging"""
- return super(QuantaMeshSSH, self).disable_paging(command=command)
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging("no pager")
- def config_mode(self, config_command='configure'):
- """Enter configuration mode."""
- return super(QuantaMeshSSH, self).config_mode(config_command=config_command)
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
- def save_config(self, cmd='', confirm=True, confirm_response=''):
- """Not Implemented"""
- raise NotImplementedError
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/rad/__init__.py b/netmiko/rad/__init__.py
new file mode 100644
index 000000000..f41afca6e
--- /dev/null
+++ b/netmiko/rad/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.rad.rad_etx import RadETXSSH
+from netmiko.rad.rad_etx import RadETXTelnet
+
+__all__ = ["RadETXSSH", "RadETXTelnet"]
diff --git a/netmiko/rad/rad_etx.py b/netmiko/rad/rad_etx.py
new file mode 100644
index 000000000..400c7a0a9
--- /dev/null
+++ b/netmiko/rad/rad_etx.py
@@ -0,0 +1,99 @@
+import time
+from typing import Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import BaseConnection
+
+
+class RadETXBase(NoEnable, BaseConnection):
+ """RAD ETX Support, Tested on RAD 203AX, 205A and 220A."""
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.disable_paging(command="config term length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "admin save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using admin save."""
+ if confirm:
+ output = self._send_command_timing_str(command_string=cmd)
+ if confirm_response:
+ output += self._send_command_timing_str(confirm_response)
+ else:
+ # Send enter by default
+ output += self._send_command_timing_str(self.RETURN)
+ else:
+ # Some devices are slow so match on trailing-prompt if you can
+ output = self._send_command_str(command_string=cmd)
+ return output
+
+ def config_mode(
+ self,
+ config_command: str = "config",
+ pattern: str = ">config",
+ re_flags: int = 0,
+ ) -> str:
+ """Enter into configuration mode on remote device."""
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def check_config_mode(
+ self, check_string: str = ">config", pattern: str = ""
+ ) -> bool:
+ """
+ Checks if the device is in configuration mode or not.
+
+ Rad config starts with baseprompt>config.
+ """
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def exit_config_mode(
+ self, exit_config: str = "exit all", pattern: str = "#"
+ ) -> str:
+ """Exit from configuration mode."""
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+
+class RadETXSSH(RadETXBase):
+ """RAD ETX SSH Support."""
+
+ def __init__(self, **kwargs: Any) -> None:
+ # Found that a global_delay_factor of 2 is needed at minimum for SSH to the Rad ETX.
+ kwargs.setdefault("global_delay_factor", 2)
+ return super().__init__(**kwargs)
+
+
+class RadETXTelnet(RadETXBase):
+ """RAD ETX Telnet Support."""
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r"#\s*$",
+ username_pattern: str = r"(?:user>)",
+ pwd_pattern: str = r"assword",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+ """
+ RAD presents with the following on login
+
+ user>
+
+ password> ****
+ """
+ self.TELNET_RETURN = self.RETURN
+ return super().telnet_login(
+ username_pattern=username_pattern,
+ alt_prompt_terminator=alt_prompt_terminator,
+ pri_prompt_terminator=pri_prompt_terminator,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
diff --git a/netmiko/raisecom/__init__.py b/netmiko/raisecom/__init__.py
new file mode 100644
index 000000000..865212095
--- /dev/null
+++ b/netmiko/raisecom/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.raisecom.raisecom_roap import RaisecomRoapSSH
+from netmiko.raisecom.raisecom_roap import RaisecomRoapTelnet
+
+__all__ = ["RaisecomRoapSSH", "RaisecomRoapTelnet"]
diff --git a/netmiko/raisecom/raisecom_roap.py b/netmiko/raisecom/raisecom_roap.py
new file mode 100644
index 000000000..c94aea1e0
--- /dev/null
+++ b/netmiko/raisecom/raisecom_roap.py
@@ -0,0 +1,157 @@
+from netmiko.cisco_base_connection import CiscoBaseConnection
+import re
+import time
+from socket import socket
+
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, ECHO, SGA, NAWS, Telnet
+from netmiko.exceptions import NetmikoAuthenticationException
+
+
+class RaisecomRoapBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging("terminal page-break disable")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """Saves Config."""
+ self.exit_config_mode()
+ self.enable()
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class RaisecomRoapSSH(RaisecomRoapBase):
+ def special_login_handler(self, delay_factor: float = 1.0) -> None:
+ """
+ Raisecom presents with the following on login (in certain OS versions)
+ Login: user
+ Password:****
+ """
+ delay_factor = self.select_delay_factor(delay_factor)
+ i = 0
+ time.sleep(delay_factor * 0.5)
+ output = ""
+ while i <= 12:
+ output = self.read_channel()
+ if output:
+ if "Login:" in output:
+ self.write_channel(self.username + self.RETURN)
+ elif "Password:" in output:
+ assert self.password is not None
+ self.write_channel(self.password + self.RETURN)
+ break
+ time.sleep(delay_factor * 1)
+ else:
+ self.write_channel(self.RETURN)
+ time.sleep(delay_factor * 1.5)
+ i += 1
+
+
+class RaisecomRoapTelnet(RaisecomRoapBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Weight:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = r"#\s*$",
+ alt_prompt_terminator: str = r">\s*$",
+ username_pattern: str = r"(Login|Username)",
+ pwd_pattern: str = r"Password",
+ delay_factor: float = 1.0,
+ max_loops: int = 20,
+ ) -> str:
+
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ delay_factor = self.select_delay_factor(delay_factor)
+ time.sleep(1 * delay_factor)
+
+ output = ""
+ return_msg = ""
+ i = 1
+ while i <= max_loops:
+ try:
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for username pattern / send username
+ if re.search(username_pattern, output, flags=re.I):
+ self.write_channel(self.username + self.TELNET_RETURN)
+ time.sleep(1 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+
+ # Search for password pattern / send password
+ if re.search(pwd_pattern, output, flags=re.I):
+ assert self.password is not None
+ self.write_channel(self.password + self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(
+ pri_prompt_terminator, output, flags=re.M
+ ) or re.search(alt_prompt_terminator, output, flags=re.M):
+ return return_msg
+
+ # Check if proper data received
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ time.sleep(0.5 * delay_factor)
+ i += 1
+ except EOFError:
+ self.remote_conn.close()
+ msg = f"Login failed: {self.host}"
+ raise NetmikoAuthenticationException(msg)
+
+ # Last try to see if we already logged in
+ self.write_channel(self.TELNET_RETURN)
+ time.sleep(0.5 * delay_factor)
+ output = self.read_channel()
+ return_msg += output
+ if re.search(pri_prompt_terminator, output, flags=re.M) or re.search(
+ alt_prompt_terminator, output, flags=re.M
+ ):
+ return return_msg
+
+ msg = f"Login failed: {self.host}"
+ self.remote_conn.close()
+ raise NetmikoAuthenticationException(msg)
diff --git a/netmiko/ruckus/__init__.py b/netmiko/ruckus/__init__.py
index e11e17cdf..dfa47d854 100644
--- a/netmiko/ruckus/__init__.py
+++ b/netmiko/ruckus/__init__.py
@@ -1,5 +1,4 @@
-from __future__ import unicode_literals
from netmiko.ruckus.ruckus_fastiron import RuckusFastironSSH
from netmiko.ruckus.ruckus_fastiron import RuckusFastironTelnet
-__all__ = ['RuckusFastironSSH', 'RuckusFastironTelnet']
+__all__ = ["RuckusFastironSSH", "RuckusFastironTelnet"]
diff --git a/netmiko/ruckus/ruckus_fastiron.py b/netmiko/ruckus/ruckus_fastiron.py
index 79819c689..2cb7a3496 100644
--- a/netmiko/ruckus/ruckus_fastiron.py
+++ b/netmiko/ruckus/ruckus_fastiron.py
@@ -1,22 +1,32 @@
-from __future__ import unicode_literals
import re
import time
+from socket import socket
+from typing import Optional, Any
+
+from telnetlib import DO, DONT, ECHO, IAC, WILL, WONT, Telnet
from netmiko.cisco_base_connection import CiscoSSHConnection
class RuckusFastironBase(CiscoSSHConnection):
"""Ruckus FastIron aka ICX support."""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""FastIron requires to be enable mode to disable paging."""
self._test_channel_read()
self.set_base_prompt()
self.enable()
self.disable_paging(command="skip-page-display")
# Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
+ time.sleep(0.3 * self.global_delay_factor)
self.clear_buffer()
- def enable(self, cmd='enable', pattern=r'(ssword|User Name)', re_flags=re.IGNORECASE):
+ def enable(
+ self,
+ cmd: str = "enable",
+ pattern: str = r"(ssword|User Name)",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
"""Enter enable mode.
With RADIUS can prompt for User Name
SSH@Lab-ICX7250>en
@@ -30,34 +40,70 @@ def enable(self, cmd='enable', pattern=r'(ssword|User Name)', re_flags=re.IGNORE
i = 1
while i < count:
self.write_channel(self.normalize_cmd(cmd))
- new_data = self.read_until_prompt_or_pattern(pattern=pattern, re_flags=re_flags)
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
output += new_data
- if 'User Name' in new_data:
+ if "User Name" in new_data:
self.write_channel(self.normalize_cmd(self.username))
- new_data = self.read_until_prompt_or_pattern(pattern=pattern, re_flags=re_flags)
+ new_data = self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
output += new_data
- if 'ssword' in new_data:
+ if "ssword" in new_data:
self.write_channel(self.normalize_cmd(self.secret))
- output += self.read_until_prompt()
- return output
+ new_data = self.read_until_prompt(read_entire_line=True)
+ output += new_data
+ if not re.search(
+ r"error.*incorrect.*password", new_data, flags=re.I
+ ):
+ break
+
time.sleep(1)
i += 1
if not self.check_enable_mode():
- msg = "Failed to enter enable mode. Please ensure you pass " \
- "the 'secret' argument to ConnectHandler."
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
raise ValueError(msg)
- def save_config(self, cmd='write mem', confirm=False):
+ return output
+
+ def save_config(
+ self, cmd: str = "write mem", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
"""Saves configuration."""
- return super(RuckusFastironBase, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
class RuckusFastironTelnet(RuckusFastironBase):
- 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(RuckusFastironTelnet, self).__init__(*args, **kwargs)
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\r\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
+
+ def _process_option(self, tsocket: socket, command: bytes, option: bytes) -> None:
+ """
+ Ruckus FastIron/ICX does not always echo commands to output by default.
+ If server expresses interest in 'ECHO' option, then reply back with 'DO
+ ECHO'
+ """
+ if option == ECHO:
+ tsocket.sendall(IAC + DO + ECHO)
+ elif command in (DO, DONT):
+ tsocket.sendall(IAC + WONT + option)
+ elif command in (WILL, WONT):
+ tsocket.sendall(IAC + DONT + option)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
class RuckusFastironSSH(RuckusFastironBase):
diff --git a/netmiko/ruijie/__init__.py b/netmiko/ruijie/__init__.py
new file mode 100644
index 000000000..f82157ae7
--- /dev/null
+++ b/netmiko/ruijie/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.ruijie.ruijie_os import RuijieOSSSH, RuijieOSTelnet
+
+__all__ = ["RuijieOSSSH", "RuijieOSTelnet"]
diff --git a/netmiko/ruijie/ruijie_os.py b/netmiko/ruijie/ruijie_os.py
new file mode 100644
index 000000000..f3a070da4
--- /dev/null
+++ b/netmiko/ruijie/ruijie_os.py
@@ -0,0 +1,39 @@
+"""Ruijie RGOS Support"""
+import time
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class RuijieOSBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ """Ruijie OS requires enable mode to set terminal width"""
+ self.enable()
+ self.set_terminal_width(command="terminal width 256", pattern="terminal")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Save config: write"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class RuijieOSSSH(RuijieOSBase):
+
+ pass
+
+
+class RuijieOSTelnet(RuijieOSBase):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ 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/scp_functions.py b/netmiko/scp_functions.py
index 4d0315d04..72aa76813 100644
--- a/netmiko/scp_functions.py
+++ b/netmiko/scp_functions.py
@@ -4,24 +4,66 @@
Supports file get and file put operations.
SCP requires a separate SSH connection for a control channel.
-
-Currently only supports Cisco IOS and Cisco ASA.
"""
-from __future__ import print_function
-from __future__ import unicode_literals
+from typing import AnyStr, Optional, Callable, Any, Dict
+from typing import TYPE_CHECKING
+from netmiko.scp_handler import BaseFileTransfer
+from netmiko.ssh_dispatcher import FileTransfer
+from netmiko.cisco.cisco_ios import InLineTransfer
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+
+
+def progress_bar(
+ filename: AnyStr, size: int, sent: int, peername: Optional[str] = None
+) -> None:
+ max_width = 50
+ if isinstance(filename, bytes):
+ filename_str = filename.decode()
+ else:
+ filename_str = filename
+ clear_screen = chr(27) + "[2J"
+ terminating_char = "|"
-from netmiko import FileTransfer, InLineTransfer
+ # Percentage done
+ percent_complete = sent / size
+ percent_str = f"{percent_complete*100:.2f}%"
+ hash_count = int(percent_complete * max_width)
+ progress = hash_count * ">"
+
+ if peername is None:
+ header_msg = f"Transferring file: {filename_str}\n"
+ else:
+ header_msg = f"Transferring file to {peername}: {filename_str}\n"
+
+ msg = f"{progress:<50}{terminating_char:1} ({percent_str})"
+ print(clear_screen)
+ print(header_msg)
+ print(msg)
-def verifyspace_and_transferfile(scp_transfer):
+def verifyspace_and_transferfile(scp_transfer: BaseFileTransfer) -> None:
"""Verify space and transfer file."""
if not scp_transfer.verify_space_available():
raise ValueError("Insufficient space available on remote device")
scp_transfer.transfer_file()
-def file_transfer(ssh_conn, source_file, dest_file, file_system=None, direction='put',
- disable_md5=False, inline_transfer=False, overwrite_file=False):
+def file_transfer(
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ disable_md5: bool = False,
+ inline_transfer: bool = False,
+ overwrite_file: bool = False,
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ verify_file: Optional[bool] = None,
+) -> Dict[str, bool]:
"""Use Secure Copy or Inline (IOS-only) to transfer files to/from network devices.
inline_transfer ONLY SUPPORTS TEXT FILES and will not support binary file transfers.
@@ -33,68 +75,81 @@ def file_transfer(ssh_conn, source_file, dest_file, file_system=None, direction=
}
"""
transferred_and_verified = {
- 'file_exists': True,
- 'file_transferred': True,
- 'file_verified': True,
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": True,
}
transferred_and_notverified = {
- 'file_exists': True,
- 'file_transferred': True,
- 'file_verified': False,
+ "file_exists": True,
+ "file_transferred": True,
+ "file_verified": False,
}
nottransferred_but_verified = {
- 'file_exists': True,
- 'file_transferred': False,
- 'file_verified': True,
+ "file_exists": True,
+ "file_transferred": False,
+ "file_verified": True,
}
- if 'cisco_ios' in ssh_conn.device_type or 'cisco_xe' in ssh_conn.device_type:
+ if "cisco_ios" in ssh_conn.device_type or "cisco_xe" in ssh_conn.device_type:
cisco_ios = True
else:
cisco_ios = False
if not cisco_ios and inline_transfer:
raise ValueError("Inline Transfer only supported for Cisco IOS/Cisco IOS-XE")
+ # Replace disable_md5 argument with verify_file argument across time
+ if verify_file is None:
+ verify_file = not disable_md5
+
scp_args = {
- 'ssh_conn': ssh_conn,
- 'source_file': source_file,
- 'dest_file': dest_file,
- 'direction': direction,
+ "ssh_conn": ssh_conn,
+ "source_file": source_file,
+ "dest_file": dest_file,
+ "direction": direction,
+ "socket_timeout": socket_timeout,
+ "progress": progress,
+ "progress4": progress4,
}
if file_system is not None:
- scp_args['file_system'] = file_system
+ scp_args["file_system"] = file_system
- TransferClass = InLineTransfer if inline_transfer else FileTransfer
+ TransferClass: Callable[..., BaseFileTransfer]
+ if inline_transfer:
+ TransferClass = InLineTransfer
+ else:
+ TransferClass = FileTransfer
with TransferClass(**scp_args) as scp_transfer:
if scp_transfer.check_file_exists():
if overwrite_file:
- if not disable_md5:
- if scp_transfer.compare_md5():
+ if verify_file:
+ if scp_transfer.verify_file():
return nottransferred_but_verified
else:
# File exists, you can overwrite it, MD5 is wrong (transfer file)
verifyspace_and_transferfile(scp_transfer)
- if scp_transfer.compare_md5():
+ if scp_transfer.verify_file():
return transferred_and_verified
else:
- raise ValueError("MD5 failure between source and destination files")
+ raise ValueError(
+ "MD5 failure between source and destination files"
+ )
else:
# File exists, you can overwrite it, but MD5 not allowed (transfer file)
verifyspace_and_transferfile(scp_transfer)
return transferred_and_notverified
else:
# File exists, but you can't overwrite it.
- if not disable_md5:
- if scp_transfer.compare_md5():
+ if verify_file:
+ if scp_transfer.verify_file():
return nottransferred_but_verified
msg = "File already exists and overwrite_file is disabled"
raise ValueError(msg)
else:
verifyspace_and_transferfile(scp_transfer)
# File doesn't exist
- if not disable_md5:
- if scp_transfer.compare_md5():
+ if verify_file:
+ if scp_transfer.verify_file():
return transferred_and_verified
else:
raise ValueError("MD5 failure between source and destination files")
diff --git a/netmiko/scp_handler.py b/netmiko/scp_handler.py
index bc5e49379..81a4f9ee1 100644
--- a/netmiko/scp_handler.py
+++ b/netmiko/scp_handler.py
@@ -4,17 +4,19 @@
Supports file get and file put operations.
SCP requires a separate SSH connection for a control channel.
-
-Currently only supports Cisco IOS and Cisco ASA.
"""
-from __future__ import print_function
-from __future__ import unicode_literals
-
+from typing import Callable, Optional, Any, Type
+from typing import TYPE_CHECKING
+from types import TracebackType
import re
import os
import hashlib
import scp
+import sys
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
class SCPConn(object):
@@ -24,30 +26,44 @@ class SCPConn(object):
Must close the SCP connection to get the file to write to the remote filesystem
"""
- def __init__(self, ssh_conn):
+ def __init__(
+ self,
+ ssh_conn: "BaseConnection",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ ) -> None:
self.ssh_ctl_chan = ssh_conn
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
self.establish_scp_conn()
- def establish_scp_conn(self):
+ def establish_scp_conn(self) -> None:
"""Establish the secure copy connection."""
ssh_connect_params = self.ssh_ctl_chan._connect_params_dict()
self.scp_conn = self.ssh_ctl_chan._build_ssh_client()
self.scp_conn.connect(**ssh_connect_params)
- self.scp_client = scp.SCPClient(self.scp_conn.get_transport())
+ self.scp_client = scp.SCPClient(
+ self.scp_conn.get_transport(),
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
- def scp_transfer_file(self, source_file, dest_file):
+ def scp_transfer_file(self, source_file: str, dest_file: str) -> None:
"""Put file using SCP (for backwards compatibility)."""
self.scp_client.put(source_file, dest_file)
- def scp_get_file(self, source_file, dest_file):
+ def scp_get_file(self, source_file: str, dest_file: str) -> None:
"""Get file using SCP."""
self.scp_client.get(source_file, dest_file)
- def scp_put_file(self, source_file, dest_file):
+ def scp_put_file(self, source_file: str, dest_file: str) -> None:
"""Put file using SCP."""
self.scp_client.put(source_file, dest_file)
- def close(self):
+ def close(self) -> None:
"""Close the SCP connection."""
self.scp_conn.close()
@@ -56,12 +72,24 @@ class BaseFileTransfer(object):
"""Class to manage SCP file transfer and associated SSH control channel."""
def __init__(
- self, ssh_conn, source_file, dest_file, file_system=None, direction="put"
- ):
+ self,
+ ssh_conn: "BaseConnection",
+ source_file: str,
+ dest_file: str,
+ file_system: Optional[str] = None,
+ direction: str = "put",
+ socket_timeout: float = 10.0,
+ progress: Optional[Callable[..., Any]] = None,
+ progress4: Optional[Callable[..., Any]] = None,
+ hash_supported: bool = True,
+ ) -> None:
self.ssh_ctl_chan = ssh_conn
self.source_file = source_file
self.dest_file = dest_file
self.direction = direction
+ self.socket_timeout = socket_timeout
+ self.progress = progress
+ self.progress4 = progress4
auto_flag = (
"cisco_ios" in ssh_conn.device_type
@@ -77,46 +105,64 @@ def __init__(
self.file_system = file_system
if direction == "put":
- self.source_md5 = self.file_md5(source_file)
+ self.source_md5 = self.file_md5(source_file) if hash_supported else None
self.file_size = os.stat(source_file).st_size
elif direction == "get":
- self.source_md5 = self.remote_md5(remote_file=source_file)
+ self.source_md5 = (
+ self.remote_md5(remote_file=source_file) if hash_supported else None
+ )
self.file_size = self.remote_file_size(remote_file=source_file)
else:
raise ValueError("Invalid direction specified")
- def __enter__(self):
+ def __enter__(self) -> "BaseFileTransfer":
"""Context manager setup"""
self.establish_scp_conn()
return self
- def __exit__(self, exc_type, exc_value, traceback):
+ def __exit__(
+ self,
+ exc_type: Optional[Type[BaseException]],
+ exc_value: Optional[BaseException],
+ traceback: Optional[TracebackType],
+ ) -> None:
"""Context manager cleanup."""
self.close_scp_chan()
- def establish_scp_conn(self):
+ def establish_scp_conn(self) -> None:
"""Establish SCP connection."""
- self.scp_conn = SCPConn(self.ssh_ctl_chan)
+ self.scp_conn = SCPConn(
+ self.ssh_ctl_chan,
+ socket_timeout=self.socket_timeout,
+ progress=self.progress,
+ progress4=self.progress4,
+ )
- def close_scp_chan(self):
+ def close_scp_chan(self) -> None:
"""Close the SCP connection to the remote network device."""
self.scp_conn.close()
- self.scp_conn = None
+ del self.scp_conn
- def remote_space_available(self, search_pattern=r"(\d+) \w+ free"):
+ def remote_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> int:
"""Return space available on remote device."""
- remote_cmd = "dir {}".format(self.file_system)
- remote_output = self.ssh_ctl_chan.send_command_expect(remote_cmd)
+ remote_cmd = f"dir {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(remote_cmd)
match = re.search(search_pattern, remote_output)
- if "kbytes" in match.group(0) or "Kbytes" in match.group(0):
- return int(match.group(1)) * 1000
- return int(match.group(1))
+ if match:
+ if "kbytes" in match.group(0) or "Kbytes" in match.group(0):
+ return int(match.group(1)) * 1000
+ return int(match.group(1))
+ else:
+ msg = (
+ f"pattern: {search_pattern} not detected in output:\n\n{remote_output}"
+ )
+ raise ValueError(msg)
- def _remote_space_available_unix(self, search_pattern=""):
+ def _remote_space_available_unix(self, search_pattern: str = "") -> int:
"""Return space available on *nix system (BSD/Linux)."""
self.ssh_ctl_chan._enter_shell()
- remote_cmd = "/bin/df -k {}".format(self.file_system)
- remote_output = self.ssh_ctl_chan.send_command(
+ remote_cmd = f"/bin/df -k {self.file_system}"
+ remote_output = self.ssh_ctl_chan._send_command_str(
remote_cmd, expect_string=r"[\$#]"
)
@@ -147,12 +193,21 @@ def _remote_space_available_unix(self, search_pattern=""):
self.ssh_ctl_chan._return_cli()
return int(space_available) * 1024
- def local_space_available(self):
+ def local_space_available(self) -> int:
"""Return space available on local filesystem."""
- destination_stats = os.statvfs(".")
- return destination_stats.f_bsize * destination_stats.f_bavail
+ if sys.platform == "win32":
+ import ctypes
+
+ free_bytes = ctypes.c_ulonglong(0)
+ ctypes.windll.kernel32.GetDiskFreeSpaceExW(
+ ctypes.c_wchar_p("."), None, None, ctypes.pointer(free_bytes)
+ )
+ return free_bytes.value
+ else:
+ destination_stats = os.statvfs(".")
+ return destination_stats.f_bsize * destination_stats.f_bavail
- def verify_space_available(self, search_pattern=r"(\d+) \w+ free"):
+ def verify_space_available(self, search_pattern: str = r"(\d+) \w+ free") -> bool:
"""Verify sufficient space is available on destination file system (return boolean)."""
if self.direction == "put":
space_avail = self.remote_space_available(search_pattern=search_pattern)
@@ -162,12 +217,12 @@ def verify_space_available(self, search_pattern=r"(\d+) \w+ free"):
return True
return False
- def check_file_exists(self, remote_cmd=""):
+ def check_file_exists(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
if self.direction == "put":
if not remote_cmd:
- remote_cmd = "dir {}/{}".format(self.file_system, self.dest_file)
- remote_out = self.ssh_ctl_chan.send_command_expect(remote_cmd)
+ remote_cmd = f"dir {self.file_system}/{self.dest_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
search_string = r"Directory of .*{0}".format(self.dest_file)
if (
"Error opening" in remote_out
@@ -181,21 +236,27 @@ def check_file_exists(self, remote_cmd=""):
raise ValueError("Unexpected output from check_file_exists")
elif self.direction == "get":
return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
- def _check_file_exists_unix(self, remote_cmd=""):
+ def _check_file_exists_unix(self, remote_cmd: str = "") -> bool:
"""Check if the dest_file already exists on the file system (return boolean)."""
if self.direction == "put":
self.ssh_ctl_chan._enter_shell()
- remote_cmd = "ls {}".format(self.file_system)
- remote_out = self.ssh_ctl_chan.send_command(
+ remote_cmd = f"/bin/ls {self.file_system}"
+ remote_out = self.ssh_ctl_chan._send_command_str(
remote_cmd, expect_string=r"[\$#]"
)
self.ssh_ctl_chan._return_cli()
return self.dest_file in remote_out
elif self.direction == "get":
return os.path.exists(self.dest_file)
+ else:
+ raise ValueError("Unexpected value for self.direction")
- def remote_file_size(self, remote_cmd="", remote_file=None):
+ def remote_file_size(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""Get the file size of the remote file."""
if remote_file is None:
if self.direction == "put":
@@ -203,12 +264,13 @@ def remote_file_size(self, remote_cmd="", remote_file=None):
elif self.direction == "get":
remote_file = self.source_file
if not remote_cmd:
- remote_cmd = "dir {}/{}".format(self.file_system, remote_file)
- remote_out = self.ssh_ctl_chan.send_command(remote_cmd)
+ remote_cmd = f"dir {self.file_system}/{remote_file}"
+ remote_out = self.ssh_ctl_chan._send_command_str(remote_cmd)
# Strip out "Directory of flash:/filename line
- remote_out = re.split(r"Directory of .*", remote_out)
- remote_out = "".join(remote_out)
+ remote_out_lines = re.split(r"Directory of .*", remote_out)
+ remote_out = "".join(remote_out_lines)
# Match line containing file name
+ assert isinstance(remote_file, str)
escape_file_name = re.escape(remote_file)
pattern = r".*({}).*".format(escape_file_name)
match = re.search(pattern, remote_out)
@@ -216,24 +278,31 @@ 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:
return int(file_size)
- def _remote_file_size_unix(self, remote_cmd="", remote_file=None):
+ def _remote_file_size_unix(
+ self, remote_cmd: str = "", remote_file: Optional[str] = None
+ ) -> int:
"""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
- remote_file = "{}/{}".format(self.file_system, remote_file)
+ remote_file = f"{self.file_system}/{remote_file}"
if not remote_cmd:
- remote_cmd = "ls -l {}".format(remote_file)
+ remote_cmd = f"/bin/ls -l {remote_file}"
self.ssh_ctl_chan._enter_shell()
- remote_out = self.ssh_ctl_chan.send_command(remote_cmd, expect_string=r"[\$#]")
+ remote_out = self.ssh_ctl_chan._send_command_str(
+ remote_cmd, expect_string=r"[\$#]"
+ )
self.ssh_ctl_chan._return_cli()
if "No such file or directory" in remote_out:
@@ -252,15 +321,30 @@ def _remote_file_size_unix(self, remote_cmd="", remote_file=None):
"Search pattern not found for remote file size during SCP transfer."
)
- def file_md5(self, file_name):
- """Compute MD5 hash of file."""
+ def file_md5(self, file_name: str, add_newline: bool = False) -> str:
+ """Compute MD5 hash of file.
+
+ add_newline is needed to support Cisco IOS MD5 calculation which expects the newline in
+ the string
+
+ Args:
+ file_name: name of file to get md5 digest of
+ add_newline: add newline to end of file contents or not
+
+ """
+ file_hash = hashlib.md5()
with open(file_name, "rb") as f:
- file_contents = f.read()
- file_hash = hashlib.md5(file_contents).hexdigest()
- return file_hash
+ while True:
+ file_contents = f.read(512)
+ if not file_contents:
+ if add_newline:
+ file_contents + b"\n"
+ break
+ file_hash.update(file_contents)
+ return file_hash.hexdigest()
@staticmethod
- def process_md5(md5_output, pattern=r"=\s+(\S+)"):
+ def process_md5(md5_output: str, pattern: str = r"=\s+(\S+)") -> str:
"""
Process the string to retrieve the MD5 hash
@@ -272,9 +356,9 @@ def process_md5(md5_output, pattern=r"=\s+(\S+)"):
if match:
return match.group(1)
else:
- raise ValueError("Invalid output from MD5 command: {}".format(md5_output))
+ raise ValueError(f"Invalid output from MD5 command: {md5_output}")
- def compare_md5(self):
+ def compare_md5(self) -> bool:
"""Compare md5 of file on network device to md5 of local file."""
if self.direction == "put":
remote_md5 = self.remote_md5()
@@ -282,8 +366,12 @@ def compare_md5(self):
elif self.direction == "get":
local_md5 = self.file_md5(self.dest_file)
return self.source_md5 == local_md5
+ else:
+ raise ValueError("Unexpected value for self.direction")
- def remote_md5(self, base_cmd="verify /md5", remote_file=None):
+ def remote_md5(
+ self, base_cmd: str = "verify /md5", remote_file: Optional[str] = None
+ ) -> str:
"""Calculate remote MD5 and returns the hash.
This command can be CPU intensive on the remote device.
@@ -293,55 +381,49 @@ def remote_md5(self, base_cmd="verify /md5", remote_file=None):
remote_file = self.dest_file
elif self.direction == "get":
remote_file = self.source_file
- remote_md5_cmd = "{} {}/{}".format(base_cmd, self.file_system, remote_file)
- dest_md5 = self.ssh_ctl_chan.send_command(remote_md5_cmd, max_loops=1500)
+ remote_md5_cmd = f"{base_cmd} {self.file_system}/{remote_file}"
+ dest_md5 = self.ssh_ctl_chan._send_command_str(remote_md5_cmd, read_timeout=300)
dest_md5 = self.process_md5(dest_md5)
return dest_md5
- def transfer_file(self):
+ def transfer_file(self) -> None:
"""SCP transfer file."""
if self.direction == "put":
self.put_file()
elif self.direction == "get":
self.get_file()
+ else:
+ raise ValueError("Unexpected value for self.direction in transfer_file")
- def get_file(self):
+ def get_file(self) -> None:
"""SCP copy the file from the remote device to local system."""
- source_file = "{}/{}".format(self.file_system, self.source_file)
+ source_file = f"{self.file_system}/{self.source_file}"
self.scp_conn.scp_get_file(source_file, self.dest_file)
self.scp_conn.close()
- def put_file(self):
+ def put_file(self) -> None:
"""SCP copy the file from the local system to the remote device."""
- destination = "{}/{}".format(self.file_system, self.dest_file)
+ destination = f"{self.file_system}/{self.dest_file}"
self.scp_conn.scp_transfer_file(self.source_file, destination)
# Must close the SCP connection to get the file written (flush)
self.scp_conn.close()
- def verify_file(self):
+ def verify_file(self) -> bool:
"""Verify the file has been transferred correctly."""
return self.compare_md5()
- def enable_scp(self, cmd=None):
+ def enable_scp(self, cmd: str = "ip scp server enable") -> None:
"""
Enable SCP on remote device.
Defaults to Cisco IOS command
"""
- if cmd is None:
- cmd = ["ip scp server enable"]
- elif not hasattr(cmd, "__iter__"):
- cmd = [cmd]
self.ssh_ctl_chan.send_config_set(cmd)
- def disable_scp(self, cmd=None):
+ def disable_scp(self, cmd: str = "no ip scp server enable") -> None:
"""
Disable SCP on remote device.
Defaults to Cisco IOS command
"""
- if cmd is None:
- cmd = ["no ip scp server enable"]
- elif not hasattr(cmd, "__iter__"):
- cmd = [cmd]
- self.ssh_ctl_chan.send_config_set(cmd)
\ No newline at end of file
+ self.ssh_ctl_chan.send_config_set(cmd)
diff --git a/netmiko/session_log.py b/netmiko/session_log.py
new file mode 100644
index 000000000..77c82c4cb
--- /dev/null
+++ b/netmiko/session_log.py
@@ -0,0 +1,70 @@
+import io
+from netmiko.utilities import write_bytes
+from typing import Dict, Any, Union, Optional, TextIO
+
+
+class SessionLog:
+ def __init__(
+ self,
+ file_name: Optional[str] = None,
+ buffered_io: Optional[io.BufferedIOBase] = None,
+ file_mode: str = "write",
+ file_encoding: str = "utf-8",
+ no_log: Dict[str, Any] = None,
+ record_writes: bool = False,
+ ) -> None:
+ if no_log is None:
+ self.no_log = {}
+ else:
+ self.no_log = no_log
+ self.file_name = file_name
+ self.file_mode = file_mode
+ self.file_encoding = file_encoding
+ self.record_writes = record_writes
+ self._session_log_close = False
+
+ # Actual file/file-handle/buffered-IO that will be written to.
+ self.session_log: Union[io.BufferedIOBase, TextIO, None]
+ if file_name is None and buffered_io:
+ self.session_log = buffered_io
+ else:
+ self.session_log = None
+
+ # Ensures last write operations prior to disconnect are recorded.
+ self.fin = False
+
+ def open(self) -> None:
+ """Open the session_log file."""
+ if self.file_name is None:
+ return None
+ if self.file_mode == "append":
+ self.session_log = open(
+ self.file_name, mode="a", encoding=self.file_encoding
+ )
+ else:
+ self.session_log = open(
+ self.file_name, mode="w", encoding=self.file_encoding
+ )
+ self._session_log_close = True
+
+ def close(self) -> None:
+ """Close the session_log file (if it is a file that we opened)."""
+ if self.session_log and self._session_log_close:
+ self.session_log.close()
+ self.session_log = None
+
+ def write(self, data: str) -> None:
+ if self.session_log is not None and len(data) > 0:
+ # Hide the password and secret in the session_log
+ for hidden_data in self.no_log.values():
+ data = data.replace(hidden_data, "********")
+
+ if isinstance(self.session_log, io.BufferedIOBase):
+ self.session_log.write(write_bytes(data, encoding=self.file_encoding))
+ else:
+ self.session_log.write(data)
+
+ assert isinstance(self.session_log, io.BufferedIOBase) or isinstance(
+ self.session_log, io.TextIOBase
+ )
+ self.session_log.flush()
diff --git a/netmiko/sixwind/__init__.py b/netmiko/sixwind/__init__.py
new file mode 100644
index 000000000..8d36e89b7
--- /dev/null
+++ b/netmiko/sixwind/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.sixwind.sixwind_os import SixwindOSSSH
+
+__all__ = ["SixwindOSSSH"]
diff --git a/netmiko/sixwind/sixwind_os.py b/netmiko/sixwind/sixwind_os.py
new file mode 100644
index 000000000..600db7bf9
--- /dev/null
+++ b/netmiko/sixwind/sixwind_os.py
@@ -0,0 +1,110 @@
+from typing import Optional, Any
+import time
+import warnings
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
+from netmiko.cisco_base_connection import CiscoBaseConnection
+
+
+class SixwindOSBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self.ansi_escape_codes = True
+ self._test_channel_read()
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """6WIND requires no-pager at the end of command, not implemented at this time."""
+ pass
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+ prompt = prompt.strip()
+ self.base_prompt = prompt
+ return self.base_prompt
+
+ def config_mode(
+ self, config_command: str = "edit running", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
+ """
+ Commit the candidate configuration.
+
+ Raise an error and return the failure if the commit fails.
+
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
+ """
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = "Failed to generate committed config"
+ command_string = "commit"
+
+ output = self.config_mode()
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ expect_string=r"#",
+ )
+ output += self.exit_config_mode()
+
+ if error_marker in output:
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
+
+ return output
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r">") -> str:
+ """Exit configuration mode."""
+
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks whether in configuration mode. Returns a boolean."""
+
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def save_config(
+ self,
+ cmd: str = "copy running startup",
+ confirm: bool = True,
+ confirm_response: str = "y",
+ ) -> str:
+ """Save Config for 6WIND"""
+
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class SixwindOSSSH(SixwindOSBase):
+
+ pass
diff --git a/netmiko/snmp_autodetect.py b/netmiko/snmp_autodetect.py
index 2779224da..e21381eca 100644
--- a/netmiko/snmp_autodetect.py
+++ b/netmiko/snmp_autodetect.py
@@ -20,9 +20,10 @@
Note, pysnmp is a required dependency for SNMPDetect and is intentionally not included in
netmiko requirements. So installation of pysnmp might be required.
"""
-from __future__ import unicode_literals
-
+from typing import Optional, Dict
+from typing.re import Pattern
import re
+
try:
from pysnmp.entity.rfc3413.oneliner import cmdgen
except ImportError:
@@ -33,39 +34,86 @@
# Higher priority indicates a better match.
SNMP_MAPPER_BASE = {
- 'arista_eos': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Arista Networks EOS.*", re.IGNORECASE),
- "priority": 99},
- 'hp_comware': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*HP Comware.*", re.IGNORECASE),
- "priority": 99},
- 'cisco_ios': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Cisco IOS Software,.*", re.IGNORECASE),
- "priority": 60},
- 'cisco_xe': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*IOS-XE Software,.*", re.IGNORECASE),
- "priority": 99},
- 'cisco_xr': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Cisco IOS XR Software.*", re.IGNORECASE),
- "priority": 99},
- 'cisco_asa': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Cisco Adaptive Security Appliance.*", re.IGNORECASE),
- "priority": 99},
- 'cisco_nxos': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Cisco NX-OS.*", re.IGNORECASE),
- "priority": 99},
- 'cisco_wlc': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r".*Cisco Controller.*", re.IGNORECASE),
- "priority": 99},
- 'f5_ltm': {"oid": ".1.3.6.1.4.1.3375.2.1.4.1.0",
- "expr": re.compile(r".*BIG-IP.*", re.IGNORECASE),
- "priority": 99},
- 'fortinet': {"oid": ".1.3.6.1.2.1.1.1.0",
- "expr": re.compile(r"Forti.*", re.IGNORECASE),
- "priority": 80},
- 'checkpoint': {"oid": ".1.3.6.1.4.1.2620.1.6.16.9.0",
- "expr": re.compile(r"CheckPoint"),
- "priority": 79},
+ "arista_eos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Arista Networks EOS.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "paloalto_panos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Palo Alto Networks.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "hp_comware": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*HP(E)? Comware.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "hp_procurve": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".ProCurve", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_ios": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco IOS Software,.*", re.IGNORECASE),
+ "priority": 60,
+ },
+ "cisco_xe": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*IOS-XE Software,.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_xr": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco IOS XR Software.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_asa": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco Adaptive Security Appliance.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_nxos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco NX-OS.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "cisco_wlc": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Cisco Controller.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "f5_tmsh": {
+ "oid": ".1.3.6.1.4.1.3375.2.1.4.1.0",
+ "expr": re.compile(r".*BIG-IP.*", re.IGNORECASE),
+ "priority": 99,
+ },
+ "fortinet": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r"Forti.*", re.IGNORECASE),
+ "priority": 80,
+ },
+ "checkpoint": {
+ "oid": ".1.3.6.1.4.1.2620.1.6.16.9.0",
+ "expr": re.compile(r"CheckPoint"),
+ "priority": 79,
+ },
+ "juniper_junos": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*Juniper.*"),
+ "priority": 99,
+ },
+ "nokia_sros": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r".*TiMOS.*"),
+ "priority": 99,
+ },
+ "dell_powerconnect": {
+ "oid": ".1.3.6.1.2.1.1.1.0",
+ "expr": re.compile(r"PowerConnect.*", re.IGNORECASE),
+ "priority": 50,
+ },
}
# Ensure all SNMP device types are supported by Netmiko
@@ -124,15 +172,25 @@ class SNMPDetect(object):
encrypt_proto : str
The SNMPv3 encryption protocol
-
Methods
-------
autodetect()
Try to determine the device type.
"""
- def __init__(self, hostname, snmp_version="v3", snmp_port=161, community=None, user="",
- auth_key="", encrypt_key="", auth_proto="sha", encrypt_proto="aes128"):
+
+ def __init__(
+ self,
+ hostname: str,
+ snmp_version: str = "v3",
+ snmp_port: int = 161,
+ community: Optional[str] = None,
+ user: str = "",
+ auth_key: str = "",
+ encrypt_key: str = "",
+ auth_proto: str = "sha",
+ encrypt_proto: str = "aes128",
+ ) -> None:
# Check that the SNMP version is matching predefined type or raise ValueError
if snmp_version == "v1" or snmp_version == "v2c":
@@ -145,19 +203,29 @@ def __init__(self, hostname, snmp_version="v3", snmp_port=161, community=None, u
raise ValueError("SNMP version must be set to 'v1', 'v2c' or 'v3'")
# Check that the SNMPv3 auth & priv parameters match allowed types
- self._snmp_v3_authentication = {"sha": cmdgen.usmHMACSHAAuthProtocol,
- "md5": cmdgen.usmHMACMD5AuthProtocol}
- self._snmp_v3_encryption = {"des": cmdgen.usmDESPrivProtocol,
- "3des": cmdgen.usm3DESEDEPrivProtocol,
- "aes128": cmdgen.usmAesCfb128Protocol,
- "aes192": cmdgen.usmAesCfb192Protocol,
- "aes256": cmdgen.usmAesCfb256Protocol}
+ self._snmp_v3_authentication = {
+ "sha": cmdgen.usmHMACSHAAuthProtocol,
+ "md5": cmdgen.usmHMACMD5AuthProtocol,
+ }
+ self._snmp_v3_encryption = {
+ "des": cmdgen.usmDESPrivProtocol,
+ "3des": cmdgen.usm3DESEDEPrivProtocol,
+ "aes128": cmdgen.usmAesCfb128Protocol,
+ "aes192": cmdgen.usmAesCfb192Protocol,
+ "aes256": cmdgen.usmAesCfb256Protocol,
+ }
if auth_proto not in self._snmp_v3_authentication.keys():
- raise ValueError("SNMP V3 'auth_proto' argument must be one of the following: {}"
- .format(self._snmp_v3_authentication.keys()))
+ raise ValueError(
+ "SNMP V3 'auth_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_authentication.keys()
+ )
+ )
if encrypt_proto not in self._snmp_v3_encryption.keys():
- raise ValueError("SNMP V3 'encrypt_proto' argument must be one of the following: {}"
- .format(self._snmp_v3_encryption.keys()))
+ raise ValueError(
+ "SNMP V3 'encrypt_proto' argument must be one of the following: {}".format(
+ self._snmp_v3_encryption.keys()
+ )
+ )
self.hostname = hostname
self.snmp_version = snmp_version
@@ -168,9 +236,9 @@ def __init__(self, hostname, snmp_version="v3", snmp_port=161, community=None, u
self.encrypt_key = encrypt_key
self.auth_proto = self._snmp_v3_authentication[auth_proto]
self.encryp_proto = self._snmp_v3_encryption[encrypt_proto]
- self._response_cache = {}
+ self._response_cache: Dict[str, str] = {}
- def _get_snmpv3(self, oid):
+ def _get_snmpv3(self, oid: str) -> str:
"""
Try to send an SNMP GET operation using SNMPv3 for the specified OID.
@@ -188,17 +256,24 @@ def _get_snmpv3(self, oid):
cmd_gen = cmdgen.CommandGenerator()
(error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
- cmdgen.UsmUserData(self.user, self.auth_key, self.encrypt_key,
- authProtocol=self.auth_proto,
- privProtocol=self.encryp_proto),
+ cmdgen.UsmUserData(
+ self.user,
+ self.auth_key,
+ self.encrypt_key,
+ authProtocol=self.auth_proto,
+ privProtocol=self.encryp_proto,
+ ),
cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
- oid, lookupNames=True, lookupValues=True)
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
if not error_detected and snmp_data[0][1]:
return str(snmp_data[0][1])
return ""
- def _get_snmpv2c(self, oid):
+ def _get_snmpv2c(self, oid: str) -> str:
"""
Try to send an SNMP GET operation using SNMPv2 for the specified OID.
@@ -218,20 +293,23 @@ def _get_snmpv2c(self, oid):
(error_detected, error_status, error_index, snmp_data) = cmd_gen.getCmd(
cmdgen.CommunityData(self.community),
cmdgen.UdpTransportTarget(snmp_target, timeout=1.5, retries=2),
- oid, lookupNames=True, lookupValues=True)
+ oid,
+ lookupNames=True,
+ lookupValues=True,
+ )
if not error_detected and snmp_data[0][1]:
return str(snmp_data[0][1])
return ""
- def _get_snmp(self, oid):
+ def _get_snmp(self, oid: str) -> str:
"""Wrapper for generic SNMP call."""
if self.snmp_version in ["v1", "v2c"]:
return self._get_snmpv2c(oid)
else:
return self._get_snmpv3(oid)
- def autodetect(self):
+ def autodetect(self) -> Optional[str]:
"""
Try to guess the device_type using SNMP GET based on the SNMP_MAPPER dict. The type which
is returned is directly matching the name in *netmiko.ssh_dispatcher.CLASS_MAPPER_BASE*
@@ -245,26 +323,29 @@ def autodetect(self):
The name of the device_type that must be running.
"""
# Convert SNMP_MAPPER to a list and sort by priority
- snmp_mapper_list = []
+ snmp_mapper_orig = []
for k, v in SNMP_MAPPER.items():
- snmp_mapper_list.append({k: v})
- snmp_mapper_list = sorted(snmp_mapper_list, key=lambda x: list(x.values())[0]['priority'])
+ snmp_mapper_orig.append({k: v})
+ snmp_mapper_list = sorted(
+ snmp_mapper_orig, key=lambda x: list(x.values())[0]["priority"] # type: ignore
+ )
snmp_mapper_list.reverse()
for entry in snmp_mapper_list:
for device_type, v in entry.items():
- oid = v['oid']
- regex = v['expr']
-
- # Used cache data if we already queryied this OID
- if self._response_cache.get(oid):
- snmp_response = self._response_cache.get(oid)
- else:
- snmp_response = self._get_snmp(oid)
- self._response_cache[oid] = snmp_response
-
- # See if we had a match
- if re.search(regex, snmp_response):
- return device_type
+ oid: str = v["oid"] # type: ignore
+ regex: Pattern = v["expr"]
+
+ # Used cache data if we already queryied this OID
+ if self._response_cache.get(oid):
+ snmp_response = self._response_cache.get(oid)
+ else:
+ snmp_response = self._get_snmp(oid)
+ self._response_cache[oid] = snmp_response
+
+ # See if we had a match
+ if re.search(regex, snmp_response):
+ assert isinstance(device_type, str)
+ return device_type
return None
diff --git a/netmiko/sophos/__init__.py b/netmiko/sophos/__init__.py
new file mode 100644
index 000000000..1e96ffb23
--- /dev/null
+++ b/netmiko/sophos/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.sophos.sophos_sfos_ssh import SophosSfosSSH
+
+__all__ = ["SophosSfosSSH"]
diff --git a/netmiko/sophos/sophos_sfos_ssh.py b/netmiko/sophos/sophos_sfos_ssh.py
new file mode 100644
index 000000000..27b34ee20
--- /dev/null
+++ b/netmiko/sophos/sophos_sfos_ssh.py
@@ -0,0 +1,39 @@
+"""SophosXG (SFOS) Firewall support"""
+import time
+from typing import Any
+
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class SophosSfosSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ """
+ Sophos Firmware Version SFOS 18.0.0 GA-Build339
+
+ Main Menu
+
+ 1. Network Configuration
+ 2. System Configuration
+ 3. Route Configuration
+ 4. Device Console
+ 5. Device Management
+ 6. VPN Management
+ 7. Shutdown/Reboot Device
+ 0. Exit
+
+ Select Menu Number [0-7]:
+ """
+ self.write_channel("4" + self.RETURN)
+ self._test_channel_read(pattern=r"[console>]")
+ self.set_base_prompt()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """Not Implemented"""
+ raise NotImplementedError
diff --git a/netmiko/ssh_auth.py b/netmiko/ssh_auth.py
new file mode 100644
index 000000000..880e9e6e3
--- /dev/null
+++ b/netmiko/ssh_auth.py
@@ -0,0 +1,12 @@
+from typing import Any
+from paramiko import SSHClient
+
+
+class SSHClient_noauth(SSHClient):
+ """Set noauth when manually handling SSH authentication."""
+
+ def _auth(self, username: str, *args: Any) -> None:
+ transport = self.get_transport()
+ assert transport is not None
+ transport.auth_none(username)
+ return
diff --git a/netmiko/ssh_autodetect.py b/netmiko/ssh_autodetect.py
index 89d0a4cf4..ac1af68b4 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.
@@ -38,10 +38,12 @@
>>> remote_device['device_type'] = best_match
>>> connection = ConnectHandler(**remote_device)
"""
-from __future__ import unicode_literals
-
+from typing import Any, List, Optional, Union, Dict
import re
import time
+
+import paramiko
+
from netmiko.ssh_dispatcher import ConnectHandler
from netmiko.base_connection import BaseConnection
@@ -49,82 +51,224 @@
# 'dispatch' key is the SSHDetect method to call. dispatch key will be popped off dictionary
# remaining keys indicate kwargs that will be passed to dispatch method.
# Note, the 'cmd' needs to avoid output paging.
-SSH_MAPPER_BASE = {
- 'alcatel_aos': {
+SSH_MAPPER_DICT = {
+ "alcatel_aos": {
+ "cmd": "show system",
+ "search_patterns": [r"Alcatel-Lucent"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "alcatel_sros": {
+ "cmd": "show version",
+ "search_patterns": ["Nokia", "Alcatel"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "apresia_aeos": {
"cmd": "show system",
- "search_patterns": ["Alcatel-Lucent"],
+ "search_patterns": ["Apresia"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "arista_eos": {
+ "cmd": "show version",
+ "search_patterns": [r"Arista"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "ciena_saos": {
+ "cmd": "software show",
+ "search_patterns": [r"saos"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_asa": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco Adaptive Security Appliance", r"Cisco ASA"],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'alcatel_sros': {
- "cmd": "show version | match TiMOS",
+ "cisco_ios": {
+ "cmd": "show version",
"search_patterns": [
- "Nokia",
- "Alcatel",
+ "Cisco IOS Software",
+ "Cisco Internetwork Operating System Software",
],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'arista_eos': {
- "cmd": "show version | inc rist",
- "search_patterns": ["Arista"],
+ "cisco_nxos": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco Nexus Operating System", r"NX-OS"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_xr": {
+ "cmd": "show version",
+ "search_patterns": [r"Cisco IOS XR"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_force10": {
+ "cmd": "show version",
+ "search_patterns": [r"Real Time Operating System Software"],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'cisco_ios': {
- "cmd": "show version | inc Cisco",
+ "dell_os9": {
+ "cmd": "show system",
"search_patterns": [
- "Cisco IOS Software",
- "Cisco Internetwork Operating System Software"
+ r"Dell Application Software Version: 9",
+ r"Dell Networking OS Version : 9",
],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'cisco_asa': {
- "cmd": "show version | inc Cisco",
- "search_patterns": ["Cisco Adaptive Security Appliance", "Cisco ASA"],
+ "dell_os10": {
+ "cmd": "show version",
+ "search_patterns": [r"Dell EMC Networking OS10.Enterprise"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "dell_powerconnect": {
+ "cmd": "show system",
+ "search_patterns": [r"PowerConnect"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "f5_tmsh": {
+ "cmd": "show sys version",
+ "search_patterns": [r"BIG-IP"],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'cisco_nxos': {
- "cmd": "show version | inc Cisco",
- "search_patterns": ["Cisco Nexus Operating System", "NX-OS"],
+ "f5_linux": {
+ "cmd": "cat /etc/issue",
+ "search_patterns": [r"BIG-IP"],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'cisco_xr': {
- "cmd": "show version | inc Cisco",
- "search_patterns": ["Cisco IOS XR"],
+ "hp_comware": {
+ "cmd": "display version",
+ "search_patterns": ["HPE Comware", "HP Comware"],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'huawei': {
- "cmd": "display version | inc Huawei",
+ "huawei": {
+ "cmd": "display version",
"search_patterns": [
- "Huawei Technologies",
- "Huawei Versatile Routing Platform Software"
+ r"Huawei Technologies",
+ r"Huawei Versatile Routing Platform Software",
],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'juniper_junos': {
- "cmd": "show version | match JUNOS",
+ "juniper_junos": {
+ "cmd": "show version",
"search_patterns": [
- "JUNOS Software Release",
- "JUNOS .+ Software",
- "JUNOS OS Kernel",
+ r"JUNOS Software Release",
+ r"JUNOS .+ Software",
+ r"JUNOS OS Kernel",
+ r"JUNOS Base Version",
],
"priority": 99,
"dispatch": "_autodetect_std",
},
- 'dell_force10': {
- "cmd": "show version | grep Type",
- "search_patterns": ["S4048-ON"],
+ "linux": {
+ "cmd": "uname -a",
+ "search_patterns": [r"Linux"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_exos": {
+ "cmd": "show version",
+ "search_patterns": [r"ExtremeXOS"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_netiron": {
+ "cmd": "show version",
+ "search_patterns": [r"(NetIron|MLX)"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_slx": {
+ "cmd": "show version",
+ "search_patterns": [r"SLX-OS Operating System Software"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "extreme_tierra": {
+ "cmd": "show version",
+ "search_patterns": [r"TierraOS Software"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "ubiquiti_edgeswitch": {
+ "cmd": "show version",
+ "search_patterns": [r"EdgeSwitch"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "cisco_wlc": {
+ "cmd": "",
+ "dispatch": "_autodetect_remote_version",
+ "search_patterns": [r"CISCO_WLC"],
+ "priority": 99,
+ },
+ "cisco_wlc_85": {
+ "cmd": "show inventory",
+ "dispatch": "_autodetect_std",
+ "search_patterns": [r"Cisco Wireless Controller"],
+ "priority": 99,
+ },
+ "mellanox_mlnxos": {
+ "cmd": "show version",
+ "search_patterns": [r"Onyx", r"SX_PPC_M460EX"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "yamaha": {
+ "cmd": "show copyright",
+ "search_patterns": [r"Yamaha Corporation"],
+ "priority": 99,
+ "dispatch": "_autodetect_std",
+ },
+ "fortinet": {
+ "cmd": "get system status",
+ "search_patterns": [r"FortiOS"],
+ "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_DICT such that the most common commands are first
+cmd_count: Dict[str, int] = {}
+for k, v in SSH_MAPPER_DICT.items():
+ my_cmd = v["cmd"]
+ assert isinstance(my_cmd, str)
+ count = cmd_count.setdefault(my_cmd, 0)
+ cmd_count[my_cmd] = count + 1
+cmd_count = {k: v for k, v in sorted(cmd_count.items(), key=lambda item: item[1])}
+
+# SSH_MAPPER_BASE is a list
+SSH_MAPPER_BASE = sorted(
+ SSH_MAPPER_DICT.items(), key=lambda item: int(cmd_count[str(item[1]["cmd"])])
+)
+SSH_MAPPER_BASE.reverse()
+
class SSHDetect(object):
"""
@@ -141,7 +285,7 @@ class SSHDetect(object):
Attributes
----------
- connection : netmiko.terminal_server.TerminalServer
+ connection : netmiko.terminal_server.TerminalServerSSH
A basic connection to the remote SSH end.
potential_matches: dict
Dict of (device_type, accuracy) that is populated through an interaction with the
@@ -153,20 +297,22 @@ class SSHDetect(object):
Try to determine the device type.
"""
- def __init__(self, *args, **kwargs):
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
Constructor of the SSHDetect class
"""
if kwargs["device_type"] != "autodetect":
raise ValueError("The connection device_type must be 'autodetect'")
+ # Always set cmd_verify to False for autodetect
+ kwargs["global_cmd_verify"] = False
self.connection = ConnectHandler(*args, **kwargs)
# Call the _test_channel_read() in base to clear initial data
output = BaseConnection._test_channel_read(self.connection)
self.initial_buffer = output
- self.potential_matches = {}
- self._results_cache = {}
+ self.potential_matches: Dict[str, int] = {}
+ self._results_cache: Dict[str, str] = {}
- def autodetect(self):
+ def autodetect(self) -> Union[str, None]:
"""
Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE
@@ -175,16 +321,22 @@ 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")
+ assert isinstance(call_method, str)
autodetect_method = getattr(self, call_method)
accuracy = autodetect_method(**tmp_dict)
if accuracy:
self.potential_matches[device_type] = accuracy
if accuracy >= 99: # Stop the loop as we are sure of our match
- best_match = sorted(self.potential_matches.items(), key=lambda t: t[1],
- reverse=True)
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
+ # WLC needs two different auto-dectect solutions
+ if "cisco_wlc_85" in best_match[0]:
+ best_match[0] = ("cisco_wlc", 99)
+
self.connection.disconnect()
return best_match[0][0]
@@ -192,11 +344,13 @@ def autodetect(self):
self.connection.disconnect()
return None
- best_match = sorted(self.potential_matches.items(), key=lambda t: t[1], reverse=True)
+ best_match = sorted(
+ self.potential_matches.items(), key=lambda t: t[1], reverse=True
+ )
self.connection.disconnect()
return best_match[0][0]
- def _send_command(self, cmd=""):
+ def _send_command(self, cmd: str = "") -> str:
"""
Handle reading/writing channel directly. It is also sanitizing the output received.
@@ -212,12 +366,11 @@ def _send_command(self, cmd=""):
"""
self.connection.write_channel(cmd + "\n")
time.sleep(1)
- output = self.connection._read_channel_timing()
- output = self.connection.strip_ansi_escape_codes(output)
+ output = self.connection.read_channel_timing()
output = self.connection.strip_backspaces(output)
return output
- def _send_command_wrapper(self, cmd):
+ def _send_command_wrapper(self, cmd: str) -> str:
"""
Send command to the remote device with a caching feature to avoid sending the same command
twice based on the SSH_MAPPER_BASE dict cmd key.
@@ -240,7 +393,56 @@ def _send_command_wrapper(self, cmd):
else:
return cached_results
- def _autodetect_std(self, cmd="", search_patterns=None, re_flags=re.I, priority=99):
+ def _autodetect_remote_version(
+ self,
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ **kwargs: Any
+ ) -> int:
+ """
+ Method to try auto-detect the device type, by matching a regular expression on the reported
+ remote version of the SSH server.
+
+ Parameters
+ ----------
+ search_patterns : list
+ A list of regular expression to look for in the reported remote SSH version
+ (default: None).
+ re_flags: re.flags, optional
+ Any flags from the python re module to modify the regular expression (default: re.I).
+ priority: int, optional
+ The confidence the match is right between 0 and 99 (default: 99).
+ """
+ invalid_responses = [r"^$"]
+
+ if not search_patterns:
+ return 0
+
+ try:
+ remote_conn = self.connection.remote_conn
+ assert isinstance(remote_conn, paramiko.Channel)
+ assert remote_conn.transport is not None
+ remote_version = remote_conn.transport.remote_version
+ for pattern in invalid_responses:
+ match = re.search(pattern, remote_version, flags=re.I)
+ if match:
+ return 0
+ for pattern in search_patterns:
+ match = re.search(pattern, remote_version, flags=re_flags)
+ if match:
+ return priority
+ except Exception:
+ return 0
+ return 0
+
+ def _autodetect_std(
+ self,
+ cmd: str = "",
+ search_patterns: Optional[List[str]] = None,
+ re_flags: int = re.IGNORECASE,
+ priority: int = 99,
+ ) -> int:
"""
Standard method to try to auto-detect the device type. This method will be called for each
device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
@@ -259,14 +461,18 @@ def _autodetect_std(self, cmd="", search_patterns=None, re_flags=re.I, priority=
The confidence the match is right between 0 and 99 (default: 99).
"""
invalid_responses = [
- r'% Invalid input detected',
- r'syntax error, expecting',
- r'Error: Unrecognized command',
- r'%Error'
+ r"% Invalid input detected",
+ r"syntax error, expecting",
+ r"Error: Unrecognized command",
+ r"%Error",
+ r"command not found",
+ r"Syntax Error: unexpected argument",
+ r"% Unrecognized command found at",
]
if not cmd or not search_patterns:
return 0
try:
+ # _send_command_wrapper will use already cached results if available
response = self._send_command_wrapper(cmd)
# Look for error conditions in output
for pattern in invalid_responses:
diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py
old mode 100644
new mode 100755
index 5010f7652..40e86ed74
--- a/netmiko/ssh_dispatcher.py
+++ b/netmiko/ssh_dispatcher.py
@@ -1,172 +1,315 @@
"""Controls selection of proper class based on the device type."""
-from __future__ import unicode_literals
-
+from typing import Any, Type, Optional
+from typing import TYPE_CHECKING
+from netmiko.exceptions import ConnectionException
+from netmiko.exceptions import NetmikoTimeoutException, NetmikoAuthenticationException
from netmiko.a10 import A10SSH
from netmiko.accedian import AccedianSSH
+from netmiko.adtran import AdtranOSSSH, AdtranOSTelnet
from netmiko.alcatel import AlcatelAosSSH
-from netmiko.alcatel import AlcatelSrosSSH
+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.avaya import AvayaErsSSH
-from netmiko.avaya import AvayaVspSSH
-from netmiko.brocade import BrocadeNetironSSH
-from netmiko.brocade import BrocadeNetironTelnet
-from netmiko.brocade import BrocadeNosSSH
+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
+from netmiko.ciena import CienaSaosSSH, CienaSaosTelnet, CienaSaosFileTransfer
from netmiko.cisco import CiscoAsaSSH, CiscoAsaFileTransfer
-from netmiko.cisco import CiscoIosSSH, CiscoIosFileTransfer, CiscoIosTelnet, CiscoIosSerial
+from netmiko.cisco import CiscoFtdSSH
+from netmiko.cisco import (
+ CiscoIosSSH,
+ CiscoIosFileTransfer,
+ CiscoIosTelnet,
+ CiscoIosSerial,
+)
from netmiko.cisco import CiscoNxosSSH, CiscoNxosFileTransfer
-from netmiko.cisco import CiscoS300SSH
+from netmiko.cisco import CiscoS300SSH, CiscoS300Telnet
from netmiko.cisco import CiscoTpTcCeSSH
+from netmiko.cisco import CiscoViptelaSSH
from netmiko.cisco import CiscoWlcSSH
-from netmiko.cisco import CiscoXrSSH, CiscoXrFileTransfer
-from netmiko.cisco import CiscoCloudnativeSSH
-from netmiko.cisco import CiscoBspSSH, CiscoBspTelnet
-from netmiko.cisco import CiscoXrTelnet
-from netmiko.cisco import CiscoCxrHa
+from netmiko.cisco import CiscoXrSSH, CiscoXrTelnet, CiscoXrFileTransfer
from netmiko.citrix import NetscalerSSH
+from netmiko.cloudgenix import CloudGenixIonSSH
from netmiko.coriant import CoriantSSH
+from netmiko.dell import DellDNOS6SSH
+from netmiko.dell import DellDNOS6Telnet
from netmiko.dell import DellForce10SSH
+from netmiko.dell import DellOS10SSH, DellOS10FileTransfer
+from netmiko.dell import DellSonicSSH
from netmiko.dell import DellPowerConnectSSH
from netmiko.dell import DellPowerConnectTelnet
-from netmiko.eltex import EltexSSH
+from netmiko.dell import DellIsilonSSH
+from netmiko.dlink import DlinkDSTelnet, DlinkDSSSH
+from netmiko.eltex import EltexSSH, EltexEsrSSH
+from netmiko.endace import EndaceSSH
from netmiko.enterasys import EnterasysSSH
-from netmiko.extreme import ExtremeSSH
+from netmiko.ericsson import EricssonIposSSH
+from netmiko.extreme import ExtremeErsSSH
+from netmiko.extreme import ExtremeExosSSH, ExtremeExosFileTransfer
+from netmiko.extreme import ExtremeExosTelnet
+from netmiko.extreme import ExtremeNetironSSH
+from netmiko.extreme import ExtremeNetironTelnet
+from netmiko.extreme import ExtremeNosSSH
+from netmiko.extreme import ExtremeSlxSSH
+from netmiko.extreme import ExtremeTierraSSH
+from netmiko.extreme import ExtremeVspSSH
from netmiko.extreme import ExtremeWingSSH
-from netmiko.extreme import ExtremeTelnet
-from netmiko.f5 import F5LtmSSH
+from netmiko.f5 import F5TmshSSH
+from netmiko.f5 import F5LinuxSSH
+from netmiko.flexvnf import FlexvnfSSH
from netmiko.fortinet import FortinetSSH
-from netmiko.hp import HPProcurveSSH, HPComwareSSH
-from netmiko.huawei import HuaweiSSH, HuaweiVrpv8SSH
-from netmiko.juniper import JuniperSSH, JuniperTelnet
+from netmiko.hp import HPProcurveSSH, HPProcurveTelnet, HPComwareSSH, HPComwareTelnet
+from netmiko.huawei import HuaweiSSH, HuaweiVrpv8SSH, HuaweiTelnet
+from netmiko.huawei import HuaweiSmartAXSSH
+from netmiko.ipinfusion import IpInfusionOcNOSSSH, IpInfusionOcNOSTelnet
+from netmiko.juniper import JuniperSSH, JuniperTelnet, JuniperScreenOsSSH
from netmiko.juniper import JuniperFileTransfer
+from netmiko.keymile import KeymileSSH, KeymileNOSSSH
from netmiko.linux import LinuxSSH, LinuxFileTransfer
-from netmiko.mellanox import MellanoxSSH
+from netmiko.mikrotik import MikrotikRouterOsSSH
+from netmiko.mikrotik import MikrotikSwitchOsSSH
+from netmiko.mellanox import MellanoxMlnxosSSH
+from netmiko.mrv import MrvLxSSH
from netmiko.mrv import MrvOptiswitchSSH
from netmiko.netapp import NetAppcDotSSH
+from netmiko.nokia import NokiaSrosSSH, NokiaSrosFileTransfer, NokiaSrosTelnet
+from netmiko.netgear import NetgearProSafeSSH
+from netmiko.oneaccess import OneaccessOneOSTelnet, OneaccessOneOSSSH
from netmiko.ovs import OvsLinuxSSH
from netmiko.paloalto import PaloAltoPanosSSH
+from netmiko.paloalto import PaloAltoPanosTelnet
from netmiko.pluribus import PluribusSSH
from netmiko.quanta import QuantaMeshSSH
+from netmiko.rad import RadETXSSH
+from netmiko.rad import RadETXTelnet
+from netmiko.raisecom import RaisecomRoapSSH
+from netmiko.raisecom import RaisecomRoapTelnet
from netmiko.ruckus import RuckusFastironSSH
from netmiko.ruckus import RuckusFastironTelnet
+from netmiko.ruijie import RuijieOSSSH, RuijieOSTelnet
+from netmiko.sixwind import SixwindOSSSH
+from netmiko.sophos import SophosSfosSSH
from netmiko.terminal_server import TerminalServerSSH
from netmiko.terminal_server import TerminalServerTelnet
+from netmiko.tplink import TPLinkJetStreamSSH, TPLinkJetStreamTelnet
+from netmiko.ubiquiti import UbiquitiEdgeRouterSSH
from netmiko.ubiquiti import UbiquitiEdgeSSH
+from netmiko.ubiquiti import UbiquitiUnifiSwitchSSH
from netmiko.vyos import VyOSSSH
+from netmiko.watchguard import WatchguardFirewareSSH
+from netmiko.yamaha import YamahaSSH
+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
+from netmiko.zyxel import ZyxelSSH
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+ from netmiko.scp_handler import BaseFileTransfer
+GenericSSH = TerminalServerSSH
+GenericTelnet = TerminalServerTelnet
# The keys of this dictionary are the supported device_types
CLASS_MAPPER_BASE = {
- 'a10': A10SSH,
- 'accedian': AccedianSSH,
- 'alcatel_aos': AlcatelAosSSH,
- 'alcatel_sros': AlcatelSrosSSH,
- 'arista_eos': AristaSSH,
- 'aruba_os': ArubaSSH,
- 'avaya_ers': AvayaErsSSH,
- 'avaya_vsp': AvayaVspSSH,
- 'brocade_fastiron': RuckusFastironSSH,
- 'brocade_netiron': BrocadeNetironSSH,
- 'brocade_nos': BrocadeNosSSH,
- 'brocade_vdx': BrocadeNosSSH,
- 'brocade_vyos': VyOSSSH,
- 'checkpoint_gaia': CheckPointGaiaSSH,
- 'calix_b6': CalixB6SSH,
- 'ciena_saos': CienaSaosSSH,
- 'cisco_asa': CiscoAsaSSH,
- 'cisco_ios': CiscoIosSSH,
- 'cisco_nxos': CiscoNxosSSH,
- 'cisco_s300': CiscoS300SSH,
- 'cisco_tp': CiscoTpTcCeSSH,
- 'cisco_wlc': CiscoWlcSSH,
- 'cisco_xe': CiscoIosSSH,
- 'cisco_xr': CiscoXrSSH,
- 'cisco_cloudnative': CiscoCloudnativeSSH,
- 'cisco_bsp': CiscoBspSSH,
- 'cisco_bsp_telnet': CiscoBspTelnet,
- 'cisco_xr_telnet': CiscoXrTelnet,
- 'cisco_cxr_ha_telnet': CiscoCxrHa,
- 'cisco_xe_telnet': CiscoIosTelnet,
- 'coriant': CoriantSSH,
- 'dell_force10': DellForce10SSH,
- 'dell_powerconnect': DellPowerConnectSSH,
- 'eltex': EltexSSH,
- 'enterasys': EnterasysSSH,
- 'extreme': ExtremeSSH,
- 'extreme_wing': ExtremeWingSSH,
- 'f5_ltm': F5LtmSSH,
- 'fortinet': FortinetSSH,
- 'generic_termserver': TerminalServerSSH,
- 'hp_comware': HPComwareSSH,
- 'hp_procurve': HPProcurveSSH,
- 'huawei': HuaweiSSH,
- 'huawei_vrpv8': HuaweiVrpv8SSH,
- 'juniper': JuniperSSH,
- 'juniper_junos': JuniperSSH,
- 'linux': LinuxSSH,
- 'mellanox': MellanoxSSH,
- 'mrv_optiswitch': MrvOptiswitchSSH,
- 'netapp_cdot': NetAppcDotSSH,
- 'netscaler': NetscalerSSH,
- 'ovs_linux': OvsLinuxSSH,
- 'paloalto_panos': PaloAltoPanosSSH,
- 'pluribus': PluribusSSH,
- 'quanta_mesh': QuantaMeshSSH,
- 'ruckus_fastiron': RuckusFastironSSH,
- 'ubiquiti_edge': UbiquitiEdgeSSH,
- 'ubiquiti_edgeswitch': UbiquitiEdgeSSH,
- 'vyatta_vyos': VyOSSSH,
- 'vyos': VyOSSSH,
+ "a10": A10SSH,
+ "accedian": AccedianSSH,
+ "adtran_os": AdtranOSSSH,
+ "alcatel_aos": AlcatelAosSSH,
+ "alcatel_sros": NokiaSrosSSH,
+ "allied_telesis_awplus": AlliedTelesisAwplusSSH,
+ "apresia_aeos": ApresiaAeosSSH,
+ "arista_eos": AristaSSH,
+ "aruba_os": ArubaSSH,
+ "aruba_osswitch": HPProcurveSSH,
+ "aruba_procurve": HPProcurveSSH,
+ "avaya_ers": ExtremeErsSSH,
+ "avaya_vsp": ExtremeVspSSH,
+ "broadcom_icos": BroadcomIcosSSH,
+ "brocade_fos": BrocadeFOSSSH,
+ "brocade_fastiron": RuckusFastironSSH,
+ "brocade_netiron": ExtremeNetironSSH,
+ "brocade_nos": ExtremeNosSSH,
+ "brocade_vdx": ExtremeNosSSH,
+ "brocade_vyos": VyOSSSH,
+ "checkpoint_gaia": CheckPointGaiaSSH,
+ "calix_b6": CalixB6SSH,
+ "cdot_cros": CdotCrosSSH,
+ "centec_os": CentecOSSSH,
+ "ciena_saos": CienaSaosSSH,
+ "cisco_asa": CiscoAsaSSH,
+ "cisco_ftd": CiscoFtdSSH,
+ "cisco_ios": CiscoIosSSH,
+ "cisco_nxos": CiscoNxosSSH,
+ "cisco_s300": CiscoS300SSH,
+ "cisco_tp": CiscoTpTcCeSSH,
+ "cisco_viptela": CiscoViptelaSSH,
+ "cisco_wlc": CiscoWlcSSH,
+ "cisco_xe": CiscoIosSSH,
+ "cisco_xr": CiscoXrSSH,
+ "cloudgenix_ion": CloudGenixIonSSH,
+ "coriant": CoriantSSH,
+ "dell_dnos9": DellForce10SSH,
+ "dell_force10": DellForce10SSH,
+ "dell_os6": DellDNOS6SSH,
+ "dell_os9": DellForce10SSH,
+ "dell_os10": DellOS10SSH,
+ "dell_sonic": DellSonicSSH,
+ "dell_powerconnect": DellPowerConnectSSH,
+ "dell_isilon": DellIsilonSSH,
+ "dlink_ds": DlinkDSSSH,
+ "endace": EndaceSSH,
+ "eltex": EltexSSH,
+ "eltex_esr": EltexEsrSSH,
+ "enterasys": EnterasysSSH,
+ "ericsson_ipos": EricssonIposSSH,
+ "extreme": ExtremeExosSSH,
+ "extreme_ers": ExtremeErsSSH,
+ "extreme_exos": ExtremeExosSSH,
+ "extreme_netiron": ExtremeNetironSSH,
+ "extreme_nos": ExtremeNosSSH,
+ "extreme_slx": ExtremeSlxSSH,
+ "extreme_tierra": ExtremeTierraSSH,
+ "extreme_vdx": ExtremeNosSSH,
+ "extreme_vsp": ExtremeVspSSH,
+ "extreme_wing": ExtremeWingSSH,
+ "f5_ltm": F5TmshSSH,
+ "f5_tmsh": F5TmshSSH,
+ "f5_linux": F5LinuxSSH,
+ "flexvnf": FlexvnfSSH,
+ "fortinet": FortinetSSH,
+ "generic": GenericSSH,
+ "generic_termserver": TerminalServerSSH,
+ "hp_comware": HPComwareSSH,
+ "hp_procurve": HPProcurveSSH,
+ "huawei": HuaweiSSH,
+ "huawei_smartax": HuaweiSmartAXSSH,
+ "huawei_olt": HuaweiSmartAXSSH,
+ "huawei_vrpv8": HuaweiVrpv8SSH,
+ "ipinfusion_ocnos": IpInfusionOcNOSSSH,
+ "juniper": JuniperSSH,
+ "juniper_junos": JuniperSSH,
+ "juniper_screenos": JuniperScreenOsSSH,
+ "keymile": KeymileSSH,
+ "keymile_nos": KeymileNOSSSH,
+ "linux": LinuxSSH,
+ "mikrotik_routeros": MikrotikRouterOsSSH,
+ "mikrotik_switchos": MikrotikSwitchOsSSH,
+ "mellanox": MellanoxMlnxosSSH,
+ "mellanox_mlnxos": MellanoxMlnxosSSH,
+ "mrv_lx": MrvLxSSH,
+ "mrv_optiswitch": MrvOptiswitchSSH,
+ "netapp_cdot": NetAppcDotSSH,
+ "netgear_prosafe": NetgearProSafeSSH,
+ "netscaler": NetscalerSSH,
+ "nokia_sros": NokiaSrosSSH,
+ "oneaccess_oneos": OneaccessOneOSSSH,
+ "ovs_linux": OvsLinuxSSH,
+ "paloalto_panos": PaloAltoPanosSSH,
+ "pluribus": PluribusSSH,
+ "quanta_mesh": QuantaMeshSSH,
+ "rad_etx": RadETXSSH,
+ "raisecom_roap": RaisecomRoapSSH,
+ "ruckus_fastiron": RuckusFastironSSH,
+ "ruijie_os": RuijieOSSSH,
+ "sixwind_os": SixwindOSSSH,
+ "sophos_sfos": SophosSfosSSH,
+ "supermicro_smis": SmciSwitchSmisSSH,
+ "tplink_jetstream": TPLinkJetStreamSSH,
+ "ubiquiti_edge": UbiquitiEdgeSSH,
+ "ubiquiti_edgerouter": UbiquitiEdgeRouterSSH,
+ "ubiquiti_edgeswitch": UbiquitiEdgeSSH,
+ "ubiquiti_unifiswitch": UbiquitiUnifiSwitchSSH,
+ "vyatta_vyos": VyOSSSH,
+ "vyos": VyOSSSH,
+ "watchguard_fireware": WatchguardFirewareSSH,
+ "zte_zxros": ZteZxrosSSH,
+ "yamaha": YamahaSSH,
+ "zyxel_os": ZyxelSSH,
}
FILE_TRANSFER_MAP = {
- 'arista_eos': AristaFileTransfer,
- 'cisco_asa': CiscoAsaFileTransfer,
- 'cisco_ios': CiscoIosFileTransfer,
- 'cisco_nxos': CiscoNxosFileTransfer,
- 'cisco_xe': CiscoIosFileTransfer,
- 'cisco_xr': CiscoXrFileTransfer,
- 'juniper_junos': JuniperFileTransfer,
- 'linux': LinuxFileTransfer,
+ "arista_eos": AristaFileTransfer,
+ "ciena_saos": CienaSaosFileTransfer,
+ "cisco_asa": CiscoAsaFileTransfer,
+ "cisco_ios": CiscoIosFileTransfer,
+ "cisco_nxos": CiscoNxosFileTransfer,
+ "cisco_xe": CiscoIosFileTransfer,
+ "cisco_xr": CiscoXrFileTransfer,
+ "dell_os10": DellOS10FileTransfer,
+ "extreme_exos": ExtremeExosFileTransfer,
+ "juniper_junos": JuniperFileTransfer,
+ "linux": LinuxFileTransfer,
+ "nokia_sros": NokiaSrosFileTransfer,
}
# Also support keys that end in _ssh
new_mapper = {}
for k, v in CLASS_MAPPER_BASE.items():
new_mapper[k] = v
- alt_key = k + u"_ssh"
+ alt_key = k + "_ssh"
new_mapper[alt_key] = v
CLASS_MAPPER = new_mapper
new_mapper = {}
for k, v in FILE_TRANSFER_MAP.items():
new_mapper[k] = v
- alt_key = k + u"_ssh"
+ alt_key = k + "_ssh"
new_mapper[alt_key] = v
FILE_TRANSFER_MAP = new_mapper
# Add telnet drivers
-CLASS_MAPPER['brocade_fastiron_telnet'] = RuckusFastironTelnet
-CLASS_MAPPER['brocade_netiron_telnet'] = BrocadeNetironTelnet
-CLASS_MAPPER['cisco_ios_telnet'] = CiscoIosTelnet
-CLASS_MAPPER['arista_eos_telnet'] = AristaTelnet
-CLASS_MAPPER['juniper_junos_telnet'] = JuniperTelnet
-CLASS_MAPPER['calix_b6_telnet'] = CalixB6Telnet
-CLASS_MAPPER['dell_powerconnect_telnet'] = DellPowerConnectTelnet
-CLASS_MAPPER['generic_termserver_telnet'] = TerminalServerTelnet
-CLASS_MAPPER['extreme_telnet'] = ExtremeTelnet
-CLASS_MAPPER['ruckus_fastiron_telnet'] = RuckusFastironTelnet
+CLASS_MAPPER["adtran_os_telnet"] = AdtranOSTelnet
+CLASS_MAPPER["apresia_aeos_telnet"] = ApresiaAeosTelnet
+CLASS_MAPPER["arista_eos_telnet"] = AristaTelnet
+CLASS_MAPPER["aruba_procurve_telnet"] = HPProcurveTelnet
+CLASS_MAPPER["brocade_fastiron_telnet"] = RuckusFastironTelnet
+CLASS_MAPPER["brocade_netiron_telnet"] = ExtremeNetironTelnet
+CLASS_MAPPER["calix_b6_telnet"] = CalixB6Telnet
+CLASS_MAPPER["centec_os_telnet"] = CentecOSTelnet
+CLASS_MAPPER["ciena_saos_telnet"] = CienaSaosTelnet
+CLASS_MAPPER["cisco_ios_telnet"] = CiscoIosTelnet
+CLASS_MAPPER["cisco_xr_telnet"] = CiscoXrTelnet
+CLASS_MAPPER["cisco_s300_telnet"] = CiscoS300Telnet
+CLASS_MAPPER["dell_dnos6_telnet"] = DellDNOS6Telnet
+CLASS_MAPPER["dell_powerconnect_telnet"] = DellPowerConnectTelnet
+CLASS_MAPPER["dlink_ds_telnet"] = DlinkDSTelnet
+CLASS_MAPPER["extreme_telnet"] = ExtremeExosTelnet
+CLASS_MAPPER["extreme_exos_telnet"] = ExtremeExosTelnet
+CLASS_MAPPER["extreme_netiron_telnet"] = ExtremeNetironTelnet
+CLASS_MAPPER["generic_telnet"] = GenericTelnet
+CLASS_MAPPER["generic_termserver_telnet"] = TerminalServerTelnet
+CLASS_MAPPER["hp_procurve_telnet"] = HPProcurveTelnet
+CLASS_MAPPER["hp_comware_telnet"] = HPComwareTelnet
+CLASS_MAPPER["huawei_telnet"] = HuaweiTelnet
+CLASS_MAPPER["huawei_olt_telnet"] = HuaweiSmartAXSSH
+CLASS_MAPPER["ipinfusion_ocnos_telnet"] = IpInfusionOcNOSTelnet
+CLASS_MAPPER["juniper_junos_telnet"] = JuniperTelnet
+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
# Add serial drivers
-CLASS_MAPPER['cisco_ios_serial'] = CiscoIosSerial
+CLASS_MAPPER["cisco_ios_serial"] = CiscoIosSerial
# Add general terminal_server driver and autodetect
-CLASS_MAPPER['terminal_server'] = TerminalServerSSH
-CLASS_MAPPER['autodetect'] = TerminalServerSSH
+CLASS_MAPPER["terminal_server"] = TerminalServerSSH
+CLASS_MAPPER["autodetect"] = TerminalServerSSH
platforms = list(CLASS_MAPPER.keys())
platforms.sort()
@@ -180,24 +323,115 @@
scp_platforms_str = "\n".join(scp_platforms)
scp_platforms_str = "\n" + scp_platforms_str
+telnet_platforms = [x for x in platforms if "telnet" in x]
+telnet_platforms_str = "\n".join(telnet_platforms)
+telnet_platforms_str = "\n" + telnet_platforms_str
+
-def ConnectHandler(*args, **kwargs):
+def ConnectHandler(*args: Any, **kwargs: Any) -> "BaseConnection":
"""Factory function selects the proper class and creates object based on device_type."""
- if kwargs['device_type'] not in platforms:
- raise ValueError('Unsupported device_type: '
- 'currently supported platforms are: {}'.format(platforms_str))
- ConnectionClass = ssh_dispatcher(kwargs['device_type'])
+ device_type = kwargs["device_type"]
+ if device_type not in platforms:
+ if device_type is None:
+ msg_str = platforms_str
+ else:
+ msg_str = telnet_platforms_str if "telnet" in device_type else platforms_str
+ raise ValueError(
+ "Unsupported 'device_type' "
+ "currently supported platforms are: {}".format(msg_str)
+ )
+ ConnectionClass = ssh_dispatcher(device_type)
return ConnectionClass(*args, **kwargs)
-def ssh_dispatcher(device_type):
+def ConnLogOnly(
+ log_file: str = "netmiko.log",
+ log_level: Optional[int] = None,
+ log_format: Optional[str] = None,
+ **kwargs: Any,
+) -> Optional["BaseConnection"]:
+ """
+ Dispatcher function that will return either: netmiko_object or None
+
+ Excluding errors in logging configuration should never generate an exception
+ all errors should be logged.
+ """
+
+ import logging
+
+ if log_level is None:
+ log_level = logging.ERROR
+ if log_format is None:
+ log_format = "%(asctime)s %(levelname)s %(name)s %(message)s"
+
+ logging.basicConfig(filename=log_file, level=log_level, format=log_format)
+ logger = logging.getLogger(__name__)
+
+ try:
+ kwargs["auto_connect"] = False
+ net_connect = ConnectHandler(**kwargs)
+ hostname = net_connect.host
+ port = net_connect.port
+ device_type = net_connect.device_type
+
+ net_connect._open()
+ msg = f"Netmiko connection succesful to {hostname}:{port}"
+ logger.info(msg)
+ return net_connect
+ except NetmikoAuthenticationException as e:
+ msg = (
+ f"Authentication failure to: {hostname}:{port} ({device_type})\n\n{str(e)}"
+ )
+ logger.error(msg)
+ return None
+ except NetmikoTimeoutException as e:
+ if "DNS failure" in str(e):
+ msg = f"Device failed due to a DNS failure, hostname {hostname}"
+ elif "TCP connection to device failed" in str(e):
+ msg = f"Netmiko was unable to reach the provided host and port: {hostname}:{port}"
+ msg += f"\n\n{str(e)}"
+ logger.error(msg)
+ return None
+ except Exception as e:
+ msg = f"An unknown exception occurred during connection:\n\n{str(e)}"
+ logger.error(msg)
+ return None
+
+
+def ConnUnify(
+ **kwargs: Any,
+) -> "BaseConnection":
+
+ try:
+ kwargs["auto_connect"] = False
+ net_connect = ConnectHandler(**kwargs)
+ hostname = net_connect.host
+ port = net_connect.port
+ device_type = net_connect.device_type
+ general_msg = f"Connection failure to {hostname}:{port} ({device_type})\n\n"
+
+ net_connect._open()
+ return net_connect
+ except NetmikoAuthenticationException as e:
+ msg = general_msg + str(e)
+ raise ConnectionException(msg)
+ except NetmikoTimeoutException as e:
+ msg = general_msg + str(e)
+ raise ConnectionException(msg)
+ except Exception as e:
+ msg = f"An unknown exception occurred during connection:\n\n{str(e)}"
+ raise ConnectionException(msg)
+
+
+def ssh_dispatcher(device_type: str) -> Type["BaseConnection"]:
"""Select the class to be instantiated based on vendor/platform."""
return CLASS_MAPPER[device_type]
-def redispatch(obj, device_type, session_prep=True):
+def redispatch(
+ obj: "BaseConnection", device_type: str, session_prep: bool = True
+) -> None:
"""Dynamically change Netmiko object's class to proper class.
-
Generally used with terminal_server device_type when you need to redispatch after interacting
with terminal server.
"""
@@ -205,17 +439,20 @@ def redispatch(obj, device_type, session_prep=True):
obj.device_type = device_type
obj.__class__ = new_class
if session_prep:
- obj.session_preparation()
+ obj._try_session_preparation()
-def FileTransfer(*args, **kwargs):
+def FileTransfer(*args: Any, **kwargs: Any) -> "BaseFileTransfer":
"""Factory function selects the proper SCP class and creates object based on device_type."""
if len(args) >= 1:
device_type = args[0].device_type
else:
- device_type = kwargs['ssh_conn'].device_type
+ device_type = kwargs["ssh_conn"].device_type
if device_type not in scp_platforms:
- raise ValueError('Unsupported SCP device_type: '
- 'currently supported platforms are: {}'.format(scp_platforms_str))
+ raise ValueError(
+ "Unsupported SCP device_type: "
+ "currently supported platforms are: {}".format(scp_platforms_str)
+ )
+ FileTransferClass: Type["BaseFileTransfer"]
FileTransferClass = FILE_TRANSFER_MAP[device_type]
return FileTransferClass(*args, **kwargs)
diff --git a/netmiko/ssh_exception.py b/netmiko/ssh_exception.py
deleted file mode 100644
index 8f408ac19..000000000
--- a/netmiko/ssh_exception.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from __future__ import unicode_literals
-from paramiko.ssh_exception import SSHException
-from paramiko.ssh_exception import AuthenticationException
-
-
-class NetMikoTimeoutException(SSHException):
- """SSH session timed trying to connect to the device."""
- pass
-
-
-class NetMikoAuthenticationException(AuthenticationException):
- """SSH authentication exception based on Paramiko AuthenticationException."""
- pass
-
-
-class PatternNotFoundException(Exception):
- """Raise when Send_command received pattern not found"""
-
- def __init__(self, *args: list, output: str='', **kwargs: dict) -> None:
- '''
- @param output: output of the send_command.
- This output can help caller to analyze what was wrong with pattern
- '''
- self.output = output
- super().__init__(*args, **kwargs)
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..cd11b14b8
--- /dev/null
+++ b/netmiko/supermicro/smci_smis.py
@@ -0,0 +1,40 @@
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from netmiko.no_enable import NoEnable
+import time
+
+
+class SmciSwitchSmisBase(NoEnable, CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """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: str = "#") -> bool:
+ """Check if in enable mode. Return boolean."""
+ return super().check_enable_mode(check_string=check_string)
+
+ def save_config(
+ self,
+ cmd: str = "write startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
+ """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/netmiko/terminal_server/__init__.py b/netmiko/terminal_server/__init__.py
index 5f78b9e9d..d8025cef5 100644
--- a/netmiko/terminal_server/__init__.py
+++ b/netmiko/terminal_server/__init__.py
@@ -1,5 +1,4 @@
-from __future__ import unicode_literals
from netmiko.terminal_server.terminal_server import TerminalServerSSH
from netmiko.terminal_server.terminal_server import TerminalServerTelnet
-__all__ = ['TerminalServerSSH', 'TerminalServerTelnet']
+__all__ = ["TerminalServerSSH", "TerminalServerTelnet"]
diff --git a/netmiko/terminal_server/terminal_server.py b/netmiko/terminal_server/terminal_server.py
index 63e897639..f059b6153 100644
--- a/netmiko/terminal_server/terminal_server.py
+++ b/netmiko/terminal_server/terminal_server.py
@@ -1,5 +1,6 @@
"""Generic Terminal Server driver."""
-from __future__ import unicode_literals
+from typing import Any
+
from netmiko.base_connection import BaseConnection
@@ -9,21 +10,24 @@ class TerminalServer(BaseConnection):
Allow direct write_channel / read_channel operations without session_preparation causing
an exception.
"""
- def session_preparation(self):
+
+ def session_preparation(self) -> None:
"""Do nothing here; base_prompt is not set; paging is not disabled."""
pass
class TerminalServerSSH(TerminalServer):
"""Generic Terminal Server driver SSH."""
+
pass
class TerminalServerTelnet(TerminalServer):
"""Generic Terminal Server driver telnet."""
- def telnet_login(self, *args, **kwargs):
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
# Disable automatic handling of username and password when using terminal server driver
pass
- def std_login(self, *args, **kwargs):
- return super(TerminalServerTelnet, self).telnet_login(*args, **kwargs)
+ def std_login(self, *args: Any, **kwargs: Any) -> str:
+ return super().telnet_login(*args, **kwargs)
diff --git a/netmiko/tplink/__init__.py b/netmiko/tplink/__init__.py
new file mode 100644
index 000000000..4e53b9a99
--- /dev/null
+++ b/netmiko/tplink/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.tplink.tplink_jetstream import TPLinkJetStreamSSH, TPLinkJetStreamTelnet
+
+__all__ = ["TPLinkJetStreamSSH", "TPLinkJetStreamTelnet"]
diff --git a/netmiko/tplink/tplink_jetstream.py b/netmiko/tplink/tplink_jetstream.py
new file mode 100644
index 000000000..659d3538d
--- /dev/null
+++ b/netmiko/tplink/tplink_jetstream.py
@@ -0,0 +1,191 @@
+import re
+import time
+from typing import Any, Optional
+
+from cryptography.hazmat.primitives.asymmetric import dsa
+from cryptography.hazmat.primitives.asymmetric.dsa import DSAParameterNumbers
+
+from netmiko import log
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.exceptions import NetmikoTimeoutException
+
+
+class TPLinkJetStreamBase(CiscoSSHConnection):
+ def __init__(self, **kwargs: Any) -> None:
+ # TP-Link doesn't have a way to set terminal width which breaks cmd_verify
+ if kwargs.get("global_cmd_verify") is None:
+ kwargs["global_cmd_verify"] = False
+ # TP-Link uses "\r\n" as default_enter for SSH and Telnet
+ if kwargs.get("default_enter") is None:
+ kwargs["default_enter"] = "\r\n"
+ return super().__init__(**kwargs)
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ """
+ delay_factor = self.select_delay_factor(delay_factor=0)
+ time.sleep(0.3 * delay_factor)
+ self.clear_buffer()
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def enable(
+ self,
+ cmd: str = "",
+ pattern: str = "ssword",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ """
+ TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+ This is necessary as "configure" is generally only available at "enable-admin" level
+
+ If the user does not have the Admin role, he will need to execute enable-admin to really
+ enable all functions.
+ """
+
+ # If end-user passes in "cmd" execute that using normal process.
+ if cmd:
+ return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+ output = ""
+ msg = (
+ "Failed to enter enable mode. Please ensure you pass "
+ "the 'secret' argument to ConnectHandler."
+ )
+
+ cmds = ["enable", "enable-admin"]
+ if not self.check_enable_mode():
+ for cmd in cmds:
+ self.write_channel(self.normalize_cmd(cmd))
+ try:
+ output += self.read_until_prompt_or_pattern(
+ pattern=pattern, re_flags=re_flags, read_entire_line=True
+ )
+ self.write_channel(self.normalize_cmd(self.secret))
+ output += self.read_until_prompt(read_entire_line=True)
+ except NetmikoTimeoutException:
+ raise ValueError(msg)
+ if not self.check_enable_mode():
+ raise ValueError(msg)
+ return output
+
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#") -> str:
+ """
+ Exit config mode.
+
+ Like the Mellanox equipment, the TP-Link Jetstream does not
+ support a single command to completely exit the configuration mode.
+
+ Consequently, need to keep checking and sending "exit".
+ """
+ output = ""
+ check_count = 12
+ while check_count >= 0:
+ if self.check_config_mode():
+ self.write_channel(self.normalize_cmd(exit_config))
+ output += self.read_until_pattern(pattern=pattern)
+ else:
+ break
+ check_count -= 1
+
+ if self.check_config_mode():
+ raise ValueError("Failed to exit configuration mode")
+ log.debug(f"exit_config_mode: {output}")
+
+ return output
+
+ def check_config_mode(
+ self, check_string: str = "(config", pattern: str = r"#"
+ ) -> bool:
+ """Check whether device is in configuration mode. Return a boolean."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = ">",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
+ """
+ Sets self.base_prompt
+
+ Used as delimiter for stripping of trailing prompt in output.
+
+ Should be set to something that is general and applies in multiple
+ contexts. For TP-Link this will be the router prompt with > or #
+ stripped off.
+
+ This will be set on logging in, but not when entering system-view
+ """
+ return super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
+
+
+class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+ def __init__(self, **kwargs: Any) -> None:
+ setattr(dsa, "_check_dsa_parameters", self._override_check_dsa_parameters)
+ return super().__init__(**kwargs)
+
+ def _override_check_dsa_parameters(self, parameters: DSAParameterNumbers) -> None:
+ """
+ Override check_dsa_parameters from cryptography's dsa.py
+
+ Without this the error below occurs:
+
+ ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+ Allows for shorter or longer parameters.p to be returned
+ from the server's host key. This is a HORRIBLE hack and a
+ security risk, please remove if possible!
+
+ By now, with firmware:
+
+ 2.0.5 Build 20200109 Rel.36203(s)
+
+ It's still not possible to remove this hack.
+ """
+ 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.")
+
+
+class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+ def telnet_login(
+ self,
+ pri_prompt_terminator: str = "#",
+ alt_prompt_terminator: str = ">",
+ username_pattern: str = r"User:",
+ pwd_pattern: str = r"Password:",
+ delay_factor: float = 1.0,
+ max_loops: int = 60,
+ ) -> str:
+ """Telnet login: can be username/password or just password."""
+ return super().telnet_login(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ username_pattern=username_pattern,
+ pwd_pattern=pwd_pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
diff --git a/netmiko/ubiquiti/__init__.py b/netmiko/ubiquiti/__init__.py
index 05bc27263..aa695a199 100644
--- a/netmiko/ubiquiti/__init__.py
+++ b/netmiko/ubiquiti/__init__.py
@@ -1,4 +1,9 @@
-from __future__ import unicode_literals
from netmiko.ubiquiti.edge_ssh import UbiquitiEdgeSSH
+from netmiko.ubiquiti.edgerouter_ssh import UbiquitiEdgeRouterSSH
+from netmiko.ubiquiti.unifiswitch_ssh import UbiquitiUnifiSwitchSSH
-__all__ = ['UbiquitiEdgeSSH']
+__all__ = [
+ "UbiquitiEdgeRouterSSH",
+ "UbiquitiEdgeSSH",
+ "UbiquitiUnifiSwitchSSH",
+]
diff --git a/netmiko/ubiquiti/edge_ssh.py b/netmiko/ubiquiti/edge_ssh.py
index b4cf5631c..bff0473c5 100644
--- a/netmiko/ubiquiti/edge_ssh.py
+++ b/netmiko/ubiquiti/edge_ssh.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+import time
from netmiko.cisco_base_connection import CiscoSSHConnection
@@ -10,22 +10,46 @@ class UbiquitiEdgeSSH(CiscoSSHConnection):
This is NOT for EdgeRouter devices.
"""
- def check_config_mode(self, check_string=')#'):
+
+ def session_preparation(self) -> None:
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.enable()
+ self.set_base_prompt()
+ self.set_terminal_width()
+ self.disable_paging()
+
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "") -> bool:
"""Checks if the device is in configuration mode or not."""
- return super(UbiquitiEdgeSSH, self).check_config_mode(check_string=check_string)
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
- def config_mode(self, config_command='configure'):
+ def config_mode(
+ self, config_command: str = "configure", pattern: str = "", re_flags: int = 0
+ ) -> str:
"""Enter configuration mode."""
- return super(UbiquitiEdgeSSH, self).config_mode(config_command=config_command)
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
- def exit_config_mode(self, exit_config='exit'):
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = r"#.*") -> str:
"""Exit configuration mode."""
- return super(UbiquitiEdgeSSH, self).exit_config_mode(exit_config=exit_config)
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
- def exit_enable_mode(self, exit_command='exit'):
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
"""Exit enable mode."""
- return super(UbiquitiEdgeSSH, self).exit_enable_mode(exit_command=exit_command)
-
- def save_config(self, cmd='write memory', confirm=False):
+ return super().exit_enable_mode(exit_command=exit_command)
+
+ def save_config(
+ self,
+ cmd: str = "write memory",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Saves configuration."""
- return super(UbiquitiEdgeSSH, self).save_config(cmd=cmd, confirm=confirm)
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
diff --git a/netmiko/ubiquiti/edgerouter_ssh.py b/netmiko/ubiquiti/edgerouter_ssh.py
new file mode 100644
index 000000000..0fb2edd0b
--- /dev/null
+++ b/netmiko/ubiquiti/edgerouter_ssh.py
@@ -0,0 +1,27 @@
+import time
+from netmiko.vyos.vyos_ssh import VyOSSSH
+
+
+class UbiquitiEdgeRouterSSH(VyOSSSH):
+ """Implement methods for interacting with EdgeOS EdgeRouter network devices."""
+
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.set_terminal_width(command="terminal width 512")
+ self.disable_paging(command="terminal length 0")
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("EdgeRouter does not support save_config confirmation.")
+ output = self._send_command_str(command_string=cmd)
+ if "Done" not in output:
+ raise ValueError(f"Save failed with following errors:\n\n{output}")
+ return output
diff --git a/netmiko/ubiquiti/unifiswitch_ssh.py b/netmiko/ubiquiti/unifiswitch_ssh.py
new file mode 100644
index 000000000..3ff0d1cb5
--- /dev/null
+++ b/netmiko/ubiquiti/unifiswitch_ssh.py
@@ -0,0 +1,40 @@
+import time
+from netmiko.ubiquiti.edge_ssh import UbiquitiEdgeSSH
+
+
+class UbiquitiUnifiSwitchSSH(UbiquitiEdgeSSH):
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+ When SSHing to a UniFi switch, the session initially starts at a Linux
+ shell. Nothing interesting can be done in this environment, however,
+ running `telnet localhost` drops the session to a more familiar
+ environment.
+ """
+
+ self._test_channel_read()
+ self.set_base_prompt()
+ self.send_command(
+ command_string="telnet localhost", expect_string=r"\(UBNT\) >"
+ )
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging()
+
+ # Clear read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def cleanup(self, command: str = "exit") -> None:
+ """Gracefully exit the SSH session."""
+ try:
+ # The pattern="" forces use of send_command_timing
+ if self.check_config_mode(pattern=""):
+ self.exit_config_mode()
+
+ # Exit from the first 'telnet localhost'
+ self.write_channel(command + self.RETURN)
+ except Exception:
+ pass
+
+ super().cleanup()
diff --git a/netmiko/utilities.py b/netmiko/utilities.py
index fd7d3896d..d06a2ccd6 100644
--- a/netmiko/utilities.py
+++ b/netmiko/utilities.py
@@ -1,108 +1,185 @@
"""Miscellaneous utility functions."""
-from __future__ import print_function
-from __future__ import unicode_literals
-
+from typing import (
+ Any,
+ AnyStr,
+ TypeVar,
+ Callable,
+ cast,
+ Optional,
+ Union,
+ List,
+ Dict,
+ Tuple,
+)
+from typing import TYPE_CHECKING
+from glob import glob
import sys
import io
import os
-import serial.tools.list_ports
-from netmiko._textfsm import _clitable as clitable
-from netmiko._textfsm._clitable import CliTableError
+from pathlib import Path
+import functools
+from datetime import datetime
+from textfsm import clitable
+from textfsm.clitable import CliTableError
+from netmiko import log
+
+# For decorators
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+if TYPE_CHECKING:
+ from netmiko.base_connection import BaseConnection
+ from os import PathLike
+
+try:
+ from ttp import ttp
+
+ TTP_INSTALLED = True
+
+except ImportError:
+ TTP_INSTALLED = False
+
+try:
+ from genie.conf.base import Device
+ from genie.libs.parser.utils import get_parser
+ from pyats.datastructures import AttrDict
+
+ GENIE_INSTALLED = True
+except ImportError:
+ GENIE_INSTALLED = False
+# If we are on python < 3.7, we need to force the import of importlib.resources backport
+if sys.version_info[:2] >= (3, 7):
+ import importlib.resources as pkg_resources
+else:
+ import importlib_resources as pkg_resources
+
+try:
+ import serial.tools.list_ports
+
+ PYSERIAL_INSTALLED = True
+except ImportError:
+ PYSERIAL_INSTALLED = False
# Dictionary mapping 'show run' for vendors with different command
SHOW_RUN_MAPPER = {
- 'juniper': 'show configuration',
- 'juniper_junos': 'show configuration',
- 'extreme': 'show configuration',
- 'extreme_wing': 'show running-config',
- 'hp_comware': 'display current-configuration',
- 'huawei': 'display current-configuration',
- 'fortinet': 'show full-configuration',
- 'checkpoint': 'show configuration',
- 'cisco_wlc': 'show run-config',
- 'enterasys': 'show running-config',
- 'dell_force10': 'show running-config',
- 'avaya_vsp': 'show running-config',
- 'avaya_ers': 'show running-config',
- 'brocade_vdx': 'show running-config',
- 'brocade_nos': 'show running-config',
- 'brocade_fastiron': 'show running-config',
- 'brocade_netiron': 'show running-config',
- 'alcatel_aos': 'show configuration snapshot',
+ "brocade_fos": "configShow",
+ "juniper": "show configuration",
+ "juniper_junos": "show configuration",
+ "extreme": "show configuration",
+ "extreme_ers": "show running-config",
+ "extreme_exos": "show configuration",
+ "extreme_netiron": "show running-config",
+ "extreme_nos": "show running-config",
+ "extreme_slx": "show running-config",
+ "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",
+ "checkpoint": "show configuration",
+ "cisco_wlc": "show run-config",
+ "enterasys": "show running-config",
+ "dell_force10": "show running-config",
+ "avaya_vsp": "show running-config",
+ "avaya_ers": "show running-config",
+ "brocade_vdx": "show running-config",
+ "brocade_nos": "show running-config",
+ "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
new_dict = {}
for k, v in SHOW_RUN_MAPPER.items():
- new_key = k + '_ssh'
+ new_key = k + "_ssh"
new_dict[k] = v
new_dict[new_key] = v
SHOW_RUN_MAPPER = new_dict
# Default location of netmiko temp directory for netmiko tools
-NETMIKO_BASE_DIR = '~/.netmiko'
+NETMIKO_BASE_DIR = "~/.netmiko"
-def load_yaml_file(yaml_file):
+def load_yaml_file(yaml_file: Union[str, bytes, "PathLike[Any]"]) -> Any:
"""Read YAML file."""
try:
import yaml
except ImportError:
sys.exit("Unable to import yaml module.")
try:
- with io.open(yaml_file, "rt", encoding='utf-8') as fname:
- return yaml.load(fname)
+ with io.open(yaml_file, "rt", encoding="utf-8") as fname:
+ return yaml.safe_load(fname)
except IOError:
- sys.exit("Unable to open YAML file: {0}".format(yaml_file))
+ sys.exit("Unable to open YAML file")
-def load_devices(file_name=None):
+def load_devices(file_name: Union[str, bytes, "PathLike[Any]", None] = None) -> Any:
"""Find and load .netmiko.yml file."""
yaml_devices_file = find_cfg_file(file_name)
return load_yaml_file(yaml_devices_file)
-def find_cfg_file(file_name=None):
- """Look for .netmiko.yml in current dir, then ~/.netmiko.yml."""
- base_file = '.netmiko.yml'
- check_files = [
- base_file,
- os.path.expanduser('~') + '/' + base_file,
- ]
- if file_name:
- check_files.insert(0, file_name)
- for test_file in check_files:
- if os.path.isfile(test_file):
- return test_file
- raise IOError("{}: file not found in current dir or home dir.".format(base_file))
-
-
-def display_inventory(my_devices):
+def find_cfg_file(
+ file_name: Union[str, bytes, "PathLike[Any]", None] = None
+) -> Union[str, bytes, "PathLike[Any]"]:
+ """
+ Search for netmiko_tools inventory file in the following order:
+ NETMIKO_TOOLS_CFG environment variable
+ Current directory
+ Home directory
+ Look for file named: .netmiko.yml or netmiko.yml
+ Also allow NETMIKO_TOOLS_CFG to point directly at a file
+ """
+ if file_name and os.path.isfile(file_name):
+ return file_name
+ optional_path = os.environ.get("NETMIKO_TOOLS_CFG", "")
+ if os.path.isfile(optional_path):
+ return optional_path
+ search_paths = [optional_path, ".", os.path.expanduser("~")]
+ # Filter optional_path if null
+ search_paths = [path for path in search_paths if path]
+ for path in search_paths:
+ files = glob(f"{path}/.netmiko.yml") + glob(f"{path}/netmiko.yml")
+ if files:
+ return files[0]
+ raise IOError(
+ ".netmiko.yml file not found in NETMIKO_TOOLS environment variable directory,"
+ " current directory, or home directory."
+ )
+
+
+def display_inventory(my_devices: Dict[str, Union[List[str], Dict[str, Any]]]) -> None:
"""Print out inventory devices and groups."""
- inventory_groups = ['all']
+ inventory_groups = ["all"]
inventory_devices = []
for k, v in my_devices.items():
if isinstance(v, list):
inventory_groups.append(k)
elif isinstance(v, dict):
- inventory_devices.append((k, v['device_type']))
+ inventory_devices.append((k, v["device_type"]))
inventory_groups.sort()
inventory_devices.sort(key=lambda x: x[0])
print("\nDevices:")
- print('-' * 40)
+ print("-" * 40)
for a_device, device_type in inventory_devices:
- device_type = " ({})".format(device_type)
- print("{:<25}{:>15}".format(a_device, device_type))
+ device_type = f" ({device_type})"
+ print(f"{a_device:<25}{device_type:>15}")
print("\n\nGroups:")
- print('-' * 40)
+ print("-" * 40)
for a_group in inventory_groups:
print(a_group)
print()
-def obtain_all_devices(my_devices):
+def obtain_all_devices(
+ my_devices: Dict[str, Union[List[str], Dict[str, Any]]]
+) -> Dict[str, Dict[str, Any]]:
"""Dynamically create 'all' group."""
new_devices = {}
for device_name, device_or_group in my_devices.items():
@@ -112,20 +189,20 @@ def obtain_all_devices(my_devices):
return new_devices
-def obtain_netmiko_filename(device_name):
+def obtain_netmiko_filename(device_name: str) -> str:
"""Create file name based on device_name."""
_, netmiko_full_dir = find_netmiko_dir()
- return "{}/{}.txt".format(netmiko_full_dir, device_name)
+ return f"{netmiko_full_dir}/{device_name}.txt"
-def write_tmp_file(device_name, output):
+def write_tmp_file(device_name: str, output: str) -> str:
file_name = obtain_netmiko_filename(device_name)
with open(file_name, "w") as f:
f.write(output)
return file_name
-def ensure_dir_exists(verify_dir):
+def ensure_dir_exists(verify_dir: str) -> None:
"""Ensure directory exists. Create if necessary."""
if not os.path.exists(verify_dir):
# Doesn't exist create dir
@@ -134,97 +211,447 @@ def ensure_dir_exists(verify_dir):
# Exists
if not os.path.isdir(verify_dir):
# Not a dir, raise an exception
- raise ValueError("{} is not a directory".format(verify_dir))
+ raise ValueError(f"{verify_dir} is not a directory")
-def find_netmiko_dir():
+def find_netmiko_dir() -> Tuple[str, str]:
"""Check environment first, then default dir"""
try:
- netmiko_base_dir = os.environ['NETMIKO_DIR']
+ netmiko_base_dir = os.environ["NETMIKO_DIR"]
except KeyError:
netmiko_base_dir = NETMIKO_BASE_DIR
netmiko_base_dir = os.path.expanduser(netmiko_base_dir)
- if netmiko_base_dir == '/':
+ if netmiko_base_dir == "/":
raise ValueError("/ cannot be netmiko_base_dir")
- netmiko_full_dir = "{}/tmp".format(netmiko_base_dir)
+ netmiko_full_dir = f"{netmiko_base_dir}/tmp"
return (netmiko_base_dir, netmiko_full_dir)
-def write_bytes(out_data):
- """Write Python2 and Python3 compatible byte stream."""
+def write_bytes(out_data: AnyStr, encoding: str = "ascii") -> bytes:
+ """Legacy for Python2 and Python3 compatible byte stream."""
if sys.version_info[0] >= 3:
- if isinstance(out_data, type(u'')):
- return out_data.encode('ascii', 'ignore')
- elif isinstance(out_data, type(b'')):
+ if isinstance(out_data, str):
+ if encoding == "utf-8":
+ return out_data.encode("utf-8")
+ else:
+ return out_data.encode("ascii", "ignore")
+ elif isinstance(out_data, bytes):
return out_data
- else:
- if isinstance(out_data, type(u'')):
- return out_data.encode('ascii', 'ignore')
- elif isinstance(out_data, type(str(''))):
- return out_data
- msg = "Invalid value for out_data neither unicode nor byte string: {0}".format(out_data)
+ msg = f"Invalid value for out_data neither unicode nor byte string: {str(out_data)}"
raise ValueError(msg)
-def check_serial_port(name):
+def check_serial_port(name: str) -> str:
"""returns valid COM Port."""
+
+ if not PYSERIAL_INSTALLED:
+ msg = (
+ "\npyserial is not installed. Please PIP install pyserial:\n\n"
+ "pip install pyserial\n\n"
+ )
+ raise ValueError(msg)
+
try:
cdc = next(serial.tools.list_ports.grep(name))
- return cdc.split()[0]
+ serial_port = cdc[0]
+ assert isinstance(serial_port, str)
+ return serial_port
except StopIteration:
- msg = "device {} not found. ".format(name)
+ msg = f"device {name} not found. "
msg += "available devices are: "
ports = list(serial.tools.list_ports.comports())
for p in ports:
- msg += "{},".format(str(p))
+ msg += f"{str(p)},"
raise ValueError(msg)
-def get_template_dir():
- """Find and return the ntc-templates/templates dir."""
- try:
- template_dir = os.environ['NET_TEXTFSM']
- index = os.path.join(template_dir, 'index')
+def get_template_dir(_skip_ntc_package: bool = False) -> str:
+ """
+ Find and return the directory containing the TextFSM index file.
+
+ Order of preference is:
+ 1) Find directory in `NET_TEXTFSM` Environment Variable.
+ 2) Check for pip installed `ntc-templates` location in this environment.
+ 3) ~/ntc-templates/ntc_templates/templates.
+
+ If `index` file is not found in any of these locations, raise ValueError
+
+ :return: directory containing the TextFSM index file
+
+ """
+
+ msg = """
+Directory containing TextFSM index file not found.
+
+Please set the NET_TEXTFSM environment variable to point at the directory containing your TextFSM
+index file.
+
+Alternatively, `pip install ntc-templates` (if using ntc-templates).
+
+"""
+
+ # Try NET_TEXTFSM environment variable
+ template_dir = os.environ.get("NET_TEXTFSM")
+ if template_dir is not None:
+ template_dir = os.path.expanduser(template_dir)
+ index = os.path.join(template_dir, "index")
if not os.path.isfile(index):
# Assume only base ./ntc-templates specified
- template_dir = os.path.join(template_dir, 'templates')
- except KeyError:
- # Construct path ~/ntc-templates/templates
- home_dir = os.path.expanduser("~")
- template_dir = os.path.join(home_dir, 'ntc-templates', 'templates')
+ template_dir = os.path.join(template_dir, "templates")
- index = os.path.join(template_dir, 'index')
+ else:
+ # Try 'pip installed' ntc-templates
+ try:
+ with pkg_resources.path(
+ package="ntc_templates", resource="parse.py"
+ ) as posix_path:
+ # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
+ template_dir = str(posix_path.parent.joinpath("templates"))
+ # This is for Netmiko automated testing
+ if _skip_ntc_package:
+ raise ModuleNotFoundError()
+
+ except ModuleNotFoundError:
+ # Finally check in ~/ntc-templates/ntc_templates/templates
+ home_dir = os.path.expanduser("~")
+ template_dir = os.path.join(
+ home_dir, "ntc-templates", "ntc_templates", "templates"
+ )
+
+ index = os.path.join(template_dir, "index")
if not os.path.isdir(template_dir) or not os.path.isfile(index):
- msg = """
-Valid ntc-templates not found, please install https://github.com/networktocode/ntc-templates
-and then set the NET_TEXTFSM environment variable to point to the ./ntc-templates/templates
-directory."""
raise ValueError(msg)
- return template_dir
+ return os.path.abspath(template_dir)
-def clitable_to_dict(cli_table):
+def clitable_to_dict(cli_table: clitable.CliTable) -> List[Dict[str, str]]:
"""Converts TextFSM cli_table object to list of dictionaries."""
- objs = []
+ return_list = []
for row in cli_table:
temp_dict = {}
for index, element in enumerate(row):
temp_dict[cli_table.header[index].lower()] = element
- objs.append(temp_dict)
- return objs
-
-
-def get_structured_data(raw_output, platform, command):
- """Convert raw CLI output to structured data using TextFSM template."""
- template_dir = get_template_dir()
- index_file = os.path.join(template_dir, 'index')
- textfsm_obj = clitable.CliTable(index_file, template_dir)
- attrs = {'Command': command, 'Platform': platform}
+ return_list.append(temp_dict)
+ return return_list
+
+
+def _textfsm_parse(
+ textfsm_obj: clitable.CliTable,
+ raw_output: str,
+ attrs: Dict[str, str],
+ template_file: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """Perform the actual TextFSM parsing using the CliTable object."""
+ tfsm_parse: Callable[..., Any] = textfsm_obj.ParseCmd
try:
# Parse output through template
- textfsm_obj.ParseCmd(raw_output, attrs)
+ if template_file is not None:
+ tfsm_parse(raw_output, templates=template_file)
+ else:
+ tfsm_parse(raw_output, attrs)
+
structured_data = clitable_to_dict(textfsm_obj)
- output = raw_output if structured_data == [] else structured_data
+ if structured_data == []:
+ return raw_output
+ else:
+ return structured_data
+ except (FileNotFoundError, CliTableError):
+ return raw_output
+
+
+def get_structured_data_textfsm(
+ raw_output: str,
+ platform: Optional[str] = None,
+ command: Optional[str] = None,
+ template: Optional[str] = None,
+) -> Union[str, List[Dict[str, str]]]:
+ """
+ Convert raw CLI output to structured data using TextFSM template.
+
+ You can use a straight TextFSM file i.e. specify "template". If no template is specified,
+ then you must use an CliTable index file.
+ """
+ if platform is None or command is None:
+ attrs = {}
+ else:
+ attrs = {"Command": command, "Platform": platform}
+
+ if template is None:
+ if attrs == {}:
+ raise ValueError(
+ "Either 'platform/command' or 'template' must be specified."
+ )
+ template_dir = get_template_dir()
+ index_file = os.path.join(template_dir, "index")
+ textfsm_obj = clitable.CliTable(index_file, template_dir)
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
+
+ # Retry the output if "cisco_xe" and not structured data
+ if platform and "cisco_xe" in platform:
+ if not isinstance(output, list):
+ attrs["Platform"] = "cisco_ios"
+ output = _textfsm_parse(textfsm_obj, raw_output, attrs)
return output
- except CliTableError:
+ else:
+ template_path = Path(os.path.expanduser(template))
+ template_file = template_path.name
+ template_dir_alt = template_path.parents[0]
+ # CliTable with no index will fall-back to a TextFSM parsing behavior
+ textfsm_obj = clitable.CliTable(template_dir=template_dir_alt)
+ return _textfsm_parse(
+ textfsm_obj, raw_output, attrs, template_file=template_file
+ )
+
+
+# For compatibility
+get_structured_data = get_structured_data_textfsm
+
+
+def get_structured_data_ttp(raw_output: str, template: str) -> Union[str, List[Any]]:
+ """
+ Convert raw CLI output to structured data using TTP template.
+
+ You can use a straight TextFSM file i.e. specify "template"
+ """
+ if not TTP_INSTALLED:
+ msg = "\nTTP is not installed. Please PIP install ttp:\n\npip install ttp\n"
+ raise ValueError(msg)
+
+ try:
+ ttp_parser = ttp(data=raw_output, template=template)
+ ttp_parser.parse(one=True)
+ result: List[Any] = ttp_parser.result(format="raw")
+ return result
+ except Exception:
return raw_output
+
+
+def run_ttp_template(
+ connection: "BaseConnection",
+ template: Union[str, bytes, "PathLike[Any]"],
+ res_kwargs: Dict[str, Any],
+ **kwargs: Any,
+) -> Any:
+ """
+ Helper function to run TTP template parsing.
+
+ :param connection: Netmiko connection object
+
+ :param template: TTP template
+
+ :param res_kwargs: ``**res_kwargs`` arguments for TTP result method
+
+ :param kwargs: ``**kwargs`` for TTP object instantiation
+ """
+ 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
+ out_list = [
+ getattr(connection, method)(command_string=command, **method_kwargs)
+ for command in commands
+ ]
+ output = "\n".join(out_list)
+
+ # 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: str, platform: str, command: str
+) -> Union[str, Dict[str, Any]]:
+ if not sys.version_info >= (3, 4):
+ raise ValueError("Genie requires Python >= 3.4")
+
+ if not GENIE_INSTALLED:
+ msg = (
+ "\nGenie and PyATS are not installed. Please PIP install both Genie and PyATS:\n"
+ "pip install genie\npip install pyats\n"
+ )
+ raise ValueError(msg)
+
+ if "cisco" not in platform:
+ return raw_output
+
+ genie_device_mapper = {
+ "cisco_ios": "ios",
+ "cisco_xe": "iosxe",
+ "cisco_xr": "iosxr",
+ "cisco_nxos": "nxos",
+ "cisco_asa": "asa",
+ }
+
+ os = None
+ # platform might be _ssh, _telnet, _serial strip that off
+ if platform.count("_") > 1:
+ base_list = platform.split("_")[:-1]
+ base_platform = "_".join(base_list)
+ else:
+ base_platform = platform
+
+ os = genie_device_mapper.get(base_platform)
+ if os is None:
+ return raw_output
+
+ # Genie specific construct for doing parsing (based on Genie in Ansible)
+ device = Device("new_device", os=os)
+ device.custom.setdefault("abstraction", {})
+ device.custom["abstraction"]["order"] = ["os"]
+ device.cli = AttrDict({"execute": None})
+ try:
+ # Test whether there is a parser for given command (return Exception if fails)
+ get_parser(command, device)
+ parsed_output: Dict[str, Any] = device.parse(command, output=raw_output)
+ return parsed_output
+ except Exception:
+ return raw_output
+
+
+def structured_data_converter(
+ raw_data: str,
+ command: str,
+ platform: str,
+ use_textfsm: bool = False,
+ use_ttp: bool = False,
+ use_genie: bool = False,
+ textfsm_template: Optional[str] = None,
+ ttp_template: Optional[str] = None,
+) -> Union[str, List[Any], Dict[str, Any]]:
+ """
+ Try structured data converters in the following order: TextFSM, TTP, Genie.
+
+ Return the first structured data found, else return the raw_data as-is.
+ """
+ command = command.strip()
+ if use_textfsm:
+ structured_output_tfsm = get_structured_data_textfsm(
+ raw_data, platform=platform, command=command, template=textfsm_template
+ )
+ if not isinstance(structured_output_tfsm, str):
+ return structured_output_tfsm
+
+ if use_ttp:
+ if ttp_template is None:
+ msg = """
+The argument 'ttp_template=/path/to/template.ttp' must be set when use_ttp=True
+"""
+ raise ValueError(msg)
+ else:
+ structured_output_ttp = get_structured_data_ttp(
+ raw_data, template=ttp_template
+ )
+
+ if not isinstance(structured_output_ttp, str):
+ return structured_output_ttp
+
+ if use_genie:
+ structured_output_genie = get_structured_data_genie(
+ raw_data, platform=platform, command=command
+ )
+ if not isinstance(structured_output_genie, str):
+ return structured_output_genie
+ return raw_data
+
+
+def select_cmd_verify(func: F) -> F:
+ """Override function cmd_verify argument with global setting."""
+
+ @functools.wraps(func)
+ def wrapper_decorator(self: "BaseConnection", *args: Any, **kwargs: Any) -> Any:
+ if self.global_cmd_verify is not None:
+ kwargs["cmd_verify"] = self.global_cmd_verify
+ return func(self, *args, **kwargs)
+
+ return cast(F, wrapper_decorator)
+
+
+def m_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(self: Any, *args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(self, *args, **kwargs)
+ end_time = datetime.now()
+ method_name = str(func)
+ print(f"{method_name}: Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+def f_exec_time(func: F) -> F:
+ @functools.wraps(func)
+ def wrapper_decorator(*args: Any, **kwargs: Any) -> Any:
+ start_time = datetime.now()
+ result = func(*args, **kwargs)
+ end_time = datetime.now()
+ print(f"Elapsed time: {end_time - start_time}")
+ return result
+
+ return cast(F, wrapper_decorator)
+
+
+def calc_old_timeout(
+ max_loops: Optional[int] = None,
+ delay_factor: Optional[float] = None,
+ loop_delay: float = 0.2,
+ old_timeout: int = 100,
+) -> float:
+ """
+ loop_delay is .2 in Netmiko 3.x
+ delay_factor would multiple the loop delay
+ Number of loops was typically 500
+
+ Thus each loop would sleep (loop_delay * delay_factor) seconds
+ That sleep would happen max_loops time
+
+ Formula is (loop_delay * delay_factor) * max_loops
+
+ There was a way Netmiko's self.timeout could override the default settings and essentially be
+ used to adjust max_loops (this was probably rarely used).
+ """
+ if max_loops is None:
+ max_loops = 500
+ if delay_factor is None:
+ delay_factor = 1.0
+ # This is the logic for having self.timeout override max_loops
+ if delay_factor == 1 and max_loops == 500:
+ max_loops = int(old_timeout / loop_delay)
+
+ return max_loops * loop_delay * delay_factor
diff --git a/netmiko/vyos/__init__.py b/netmiko/vyos/__init__.py
index 89ba6c14d..b5c586e36 100644
--- a/netmiko/vyos/__init__.py
+++ b/netmiko/vyos/__init__.py
@@ -1,4 +1,3 @@
-from __future__ import unicode_literals
from netmiko.vyos.vyos_ssh import VyOSSSH
-__all__ = ['VyOSSSH']
+__all__ = ["VyOSSSH"]
diff --git a/netmiko/vyos/vyos_ssh.py b/netmiko/vyos/vyos_ssh.py
index f44b6e265..9b3652648 100644
--- a/netmiko/vyos/vyos_ssh.py
+++ b/netmiko/vyos/vyos_ssh.py
@@ -1,54 +1,62 @@
-from __future__ import print_function
-from __future__ import unicode_literals
+from typing import Optional, Union, Sequence, TextIO, Any
import time
+import warnings
+import re
+from netmiko.no_enable import NoEnable
+from netmiko.base_connection import DELAY_FACTOR_DEPR_SIMPLE_MSG
from netmiko.cisco_base_connection import CiscoSSHConnection
-class VyOSSSH(CiscoSSHConnection):
+class VyOSSSH(NoEnable, CiscoSSHConnection):
"""Implement methods for interacting with VyOS network devices."""
- def session_preparation(self):
+ def session_preparation(self) -> None:
"""Prepare the session after the connection has been established."""
self._test_channel_read()
self.set_base_prompt()
+ self.set_terminal_width(command="set terminal width 512", pattern="terminal")
self.disable_paging(command="set terminal length 0")
# Clear the read buffer
- time.sleep(.3 * self.global_delay_factor)
+ time.sleep(0.3 * self.global_delay_factor)
self.clear_buffer()
- def check_enable_mode(self, *args, **kwargs):
- """No enable mode on VyOS."""
- pass
-
- def enable(self, *args, **kwargs):
- """No enable mode on VyOS."""
- pass
-
- def exit_enable_mode(self, *args, **kwargs):
- """No enable mode on VyOS."""
- pass
-
- def check_config_mode(self, check_string='#'):
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
"""Checks if the device is in configuration mode"""
- return super(VyOSSSH, self).check_config_mode(check_string=check_string)
-
- def config_mode(self, config_command='configure', pattern=r'[edit]'):
- """Enter configuration mode."""
- return super(VyOSSSH, self).config_mode(config_command=config_command, pattern=pattern)
-
- def exit_config_mode(self, exit_config='exit', pattern=r'exit'):
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "configure",
+ pattern: str = r"\[edit\]",
+ re_flags: int = 0,
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(
+ self, exit_config: str = "exit", pattern: str = r"exit"
+ ) -> str:
"""Exit configuration mode"""
output = ""
if self.check_config_mode():
- output = self.send_command_timing(exit_config, strip_prompt=False, strip_command=False)
- if 'Cannot exit: configuration modified' in output:
- output += self.send_command_timing('exit discard', strip_prompt=False,
- strip_command=False)
+ output = self._send_command_timing_str(
+ exit_config, strip_prompt=False, strip_command=False
+ )
+ if "Cannot exit: configuration modified" in output:
+ output += self._send_command_timing_str(
+ "exit discard", strip_prompt=False, strip_command=False
+ )
if self.check_config_mode():
raise ValueError("Failed to exit configuration mode")
return output
- def commit(self, comment='', delay_factor=.1):
+ def commit(
+ self,
+ comment: str = "",
+ read_timeout: float = 120.0,
+ delay_factor: Optional[float] = None,
+ ) -> str:
"""
Commit the candidate configuration.
@@ -60,43 +68,73 @@ def commit(self, comment='', delay_factor=.1):
comment:
command_string = commit comment
+ delay_factor: Deprecated in Netmiko 4.x. Will be eliminated in Netmiko 5.
+
"""
- delay_factor = self.select_delay_factor(delay_factor)
- error_marker = 'Failed to generate committed config'
- command_string = 'commit'
+
+ if delay_factor is not None:
+ warnings.warn(DELAY_FACTOR_DEPR_SIMPLE_MSG, DeprecationWarning)
+
+ error_marker = ["Failed to generate committed config", "Commit failed"]
+ command_string = "commit"
if comment:
- command_string += ' comment "{}"'.format(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 error_marker in output:
- raise ValueError('Commit failed with following errors:\n\n{}'.format(output))
+ output += self._send_command_str(
+ command_string,
+ strip_prompt=False,
+ strip_command=False,
+ read_timeout=read_timeout,
+ )
+
+ if any(x in output for x in error_marker):
+ raise ValueError(f"Commit failed with following errors:\n\n{output}")
return output
- def set_base_prompt(self, pri_prompt_terminator='$', alt_prompt_terminator='#',
- delay_factor=1):
+ def set_base_prompt(
+ self,
+ pri_prompt_terminator: str = "$",
+ alt_prompt_terminator: str = "#",
+ delay_factor: float = 1.0,
+ pattern: Optional[str] = None,
+ ) -> str:
"""Sets self.base_prompt: used as delimiter for stripping of trailing prompt in output."""
- prompt = super(VyOSSSH, self).set_base_prompt(pri_prompt_terminator=pri_prompt_terminator,
- alt_prompt_terminator=alt_prompt_terminator,
- delay_factor=delay_factor)
+
+ # VyOS can have a third terminator; switch to a pattern solution
+ if pattern is None:
+ pri_term = re.escape(pri_prompt_terminator)
+ alt_term = re.escape(alt_prompt_terminator)
+ third_terminator = re.escape(">")
+ pattern = rf"({pri_term}|{alt_term}|{third_terminator})"
+
+ prompt = super().set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor,
+ pattern=pattern,
+ )
# Set prompt to user@hostname (remove two additional characters)
self.base_prompt = prompt[:-2].strip()
return self.base_prompt
- def send_config_set(self, config_commands=None, exit_config_mode=False, delay_factor=1,
- max_loops=150, strip_prompt=False, strip_command=False,
- config_mode_command=None):
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ **kwargs: Any,
+ ) -> str:
"""Remain in configuration mode."""
- return super(VyOSSSH, self).send_config_set(config_commands=config_commands,
- exit_config_mode=exit_config_mode,
- delay_factor=delay_factor, max_loops=max_loops,
- strip_prompt=strip_prompt,
- strip_command=strip_command,
- config_mode_command=config_mode_command)
-
- def save_config(self, cmd='', confirm=True, confirm_response=''):
+ return super().send_config_set(
+ config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs
+ )
+
+ def save_config(
+ self,
+ cmd: str = "copy running-config startup-config",
+ confirm: bool = False,
+ confirm_response: str = "",
+ ) -> str:
"""Not Implemented"""
raise NotImplementedError
diff --git a/netmiko/watchguard/__init__.py b/netmiko/watchguard/__init__.py
new file mode 100644
index 000000000..7cfbe7bda
--- /dev/null
+++ b/netmiko/watchguard/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.watchguard.fireware_ssh import WatchguardFirewareSSH
+
+__all__ = ["WatchguardFirewareSSH"]
diff --git a/netmiko/watchguard/fireware_ssh.py b/netmiko/watchguard/fireware_ssh.py
new file mode 100644
index 000000000..f4bcaab3e
--- /dev/null
+++ b/netmiko/watchguard/fireware_ssh.py
@@ -0,0 +1,42 @@
+import time
+from typing import Any
+
+from netmiko.base_connection import BaseConnection
+
+
+class WatchguardFirewareSSH(BaseConnection):
+ """
+ Implements methods for communicating with Watchguard Firebox firewalls.
+ """
+
+ def session_preparation(self) -> None:
+ """
+ Prepare the session after the connection has been established.
+
+ Set the base prompt for interaction ('#').
+ """
+ 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_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "configure", pattern: str = r"\#", re_flags: int = 0
+ ) -> str:
+ return super().config_mode(
+ config_command=config_command, pattern=pattern, re_flags=re_flags
+ )
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = "#") -> str:
+ return super().exit_config_mode(exit_config=exit_config, pattern=pattern)
+
+ def save_config(self, *args: Any, **kwargs: Any) -> str:
+ """No save config on Watchguard."""
+ pass
diff --git a/netmiko/yamaha/__init__.py b/netmiko/yamaha/__init__.py
new file mode 100644
index 000000000..0fd92834e
--- /dev/null
+++ b/netmiko/yamaha/__init__.py
@@ -0,0 +1,4 @@
+from __future__ import unicode_literals
+from netmiko.yamaha.yamaha import YamahaSSH, YamahaTelnet
+
+__all__ = ["YamahaSSH", "YamahaTelnet"]
diff --git a/netmiko/yamaha/yamaha.py b/netmiko/yamaha/yamaha.py
new file mode 100644
index 000000000..986ababf7
--- /dev/null
+++ b/netmiko/yamaha/yamaha.py
@@ -0,0 +1,91 @@
+import time
+import re
+from typing import Any, Optional
+
+from netmiko.base_connection import BaseConnection
+
+
+class YamahaBase(BaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging(command="console lines infinity")
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_enable_mode(self, check_string: str = "#") -> bool:
+ return super().check_enable_mode(check_string=check_string)
+
+ def enable(
+ self,
+ cmd: str = "administrator",
+ pattern: str = r"Password",
+ enable_pattern: Optional[str] = None,
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return super().enable(
+ cmd=cmd, pattern=pattern, enable_pattern=enable_pattern, re_flags=re_flags
+ )
+
+ def exit_enable_mode(self, exit_command: str = "exit") -> str:
+ """
+ When any changes have been made, the prompt 'Save new configuration ? (Y/N)'
+ appears before exiting. Ignore this by entering 'N'.
+ """
+ output = ""
+ if self.check_enable_mode():
+ self.write_channel(self.normalize_cmd(exit_command))
+ time.sleep(1)
+ output = self.read_channel()
+ if "(Y/N)" in output:
+ self.write_channel("N")
+ if self.base_prompt not in output:
+ output += self.read_until_prompt(read_entire_line=True)
+ if self.check_enable_mode():
+ raise ValueError("Failed to exit enable mode.")
+ return output
+
+ def check_config_mode(self, check_string: str = "#", pattern: str = "") -> bool:
+ """Checks if the device is in administrator mode or not."""
+ return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+ def config_mode(
+ self,
+ config_command: str = "administrator",
+ pattern: str = "Password",
+ re_flags: int = re.IGNORECASE,
+ ) -> str:
+ return self.enable(cmd=config_command, pattern=pattern, re_flags=re_flags)
+
+ def exit_config_mode(self, exit_config: str = "exit", pattern: str = ">") -> str:
+ """
+ No action taken. Call 'exit_enable_mode()' to explicitly exit Administration
+ Level.
+ """
+ return ""
+
+ def save_config(
+ self, cmd: str = "save", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config."""
+ if confirm is True:
+ raise ValueError("Yamaha does not support save_config confirmation.")
+ self.enable()
+ # Some devices are slow so match on trailing-prompt if you can
+ return self._send_command_str(command_string=cmd)
+
+
+class YamahaSSH(YamahaBase):
+ """Yamaha SSH driver."""
+
+ pass
+
+
+class YamahaTelnet(YamahaBase):
+ """Yamaha Telnet driver."""
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
+ default_enter = kwargs.get("default_enter")
+ kwargs["default_enter"] = "\n" if default_enter is None else default_enter
+ super().__init__(*args, **kwargs)
diff --git a/netmiko/zte/__init__.py b/netmiko/zte/__init__.py
new file mode 100644
index 000000000..447a015c4
--- /dev/null
+++ b/netmiko/zte/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.zte.zte_zxros import ZteZxrosSSH
+from netmiko.zte.zte_zxros import ZteZxrosTelnet
+
+__all__ = ["ZteZxrosSSH", "ZteZxrosTelnet"]
diff --git a/netmiko/zte/zte_zxros.py b/netmiko/zte/zte_zxros.py
new file mode 100644
index 000000000..bd641b979
--- /dev/null
+++ b/netmiko/zte/zte_zxros.py
@@ -0,0 +1,64 @@
+import time
+from socket import socket
+from typing import Any
+
+from netmiko.cisco_base_connection import CiscoBaseConnection
+from telnetlib import IAC, DO, DONT, WILL, WONT, SB, SE, ECHO, SGA, NAWS, Telnet
+
+
+class ZteZxrosBase(CiscoBaseConnection):
+ def session_preparation(self) -> None:
+ """Prepare the session after the connection has been established."""
+ self._test_channel_read(pattern=r"[>#]")
+ self.set_base_prompt()
+ self.disable_paging()
+ # Clear the read buffer
+ time.sleep(0.3 * self.global_delay_factor)
+ self.clear_buffer()
+
+ def check_config_mode(self, check_string: str = ")#", pattern: str = "#") -> bool:
+ """
+ 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: str = "write", confirm: bool = False, confirm_response: str = ""
+ ) -> str:
+ """Saves Config Using Copy Run Start"""
+ return super().save_config(
+ cmd=cmd, confirm=confirm, confirm_response=confirm_response
+ )
+
+
+class ZteZxrosSSH(ZteZxrosBase):
+ pass
+
+
+class ZteZxrosTelnet(ZteZxrosBase):
+ @staticmethod
+ def _process_option(telnet_sock: socket, cmd: bytes, opt: bytes) -> None:
+ """
+ ZTE need manually reply DO ECHO to enable echo command.
+ enable ECHO, SGA, set window size to [500, 50]
+ """
+ if cmd == WILL:
+ if opt in [ECHO, SGA]:
+ # reply DO ECHO / DO SGA
+ telnet_sock.sendall(IAC + DO + opt)
+ else:
+ telnet_sock.sendall(IAC + DONT + opt)
+ elif cmd == DO:
+ if opt == NAWS:
+ # negotiate about window size
+ telnet_sock.sendall(IAC + WILL + opt)
+ # Width:500, Height:50
+ telnet_sock.sendall(IAC + SB + NAWS + b"\x01\xf4\x00\x32" + IAC + SE)
+ else:
+ telnet_sock.sendall(IAC + WONT + opt)
+
+ def telnet_login(self, *args: Any, **kwargs: Any) -> str:
+ # set callback function to handle telnet options.
+ assert isinstance(self.remote_conn, Telnet)
+ self.remote_conn.set_option_negotiation_callback(self._process_option)
+ return super().telnet_login(*args, **kwargs)
diff --git a/netmiko/zyxel/__init__.py b/netmiko/zyxel/__init__.py
new file mode 100644
index 000000000..3ffb19341
--- /dev/null
+++ b/netmiko/zyxel/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.zyxel.zyxel_ssh import ZyxelSSH
+
+
+__all__ = ["ZyxelSSH"]
diff --git a/netmiko/zyxel/zyxel_ssh.py b/netmiko/zyxel/zyxel_ssh.py
new file mode 100644
index 000000000..79fb4292c
--- /dev/null
+++ b/netmiko/zyxel/zyxel_ssh.py
@@ -0,0 +1,30 @@
+from typing import Any, Sequence, TextIO, Union
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.no_enable import NoEnable
+from netmiko.no_config import NoConfig
+
+
+class ZyxelSSH(NoEnable, NoConfig, CiscoSSHConnection):
+ def disable_paging(self, *args: Any, **kwargs: Any) -> str:
+ """No paging on Zyxel"""
+ return ""
+
+ def send_config_set(
+ self,
+ config_commands: Union[str, Sequence[str], TextIO, None] = None,
+ exit_config_mode: bool = False,
+ enter_config_mode: bool = False,
+ **kwargs: Any
+ ) -> str:
+ """No config mode on Zyxel"""
+ return super().send_config_set(
+ config_commands=config_commands,
+ exit_config_mode=exit_config_mode,
+ enter_config_mode=enter_config_mode,
+ **kwargs
+ )
+
+ def session_preparation(self) -> None:
+ super().session_preparation()
+ # Zyxel switches output ansi codes
+ self.ansi_escape_codes = True
diff --git a/release_process.txt b/release_process.txt
index 1586c9014..2656dd36b 100644
--- a/release_process.txt
+++ b/release_process.txt
@@ -1,15 +1,26 @@
-# Use pynetcio machine
+# Use pydev1 machine
+# Use virtual environment = py3_netmiko
+
+# Run the following command to update docs:
+$ pdoc3 --html --output-dir docs netmiko --force
+
+# Docs will be hosted via GitHub Pages in the master branch...
+# 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
# 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
# Create a tag for the version
-$ git tag -a v1.4.1 -m "Version 1.4.1 Release"
-$ git push origin
+git tag -a v3.3.3 -m "Version 3.3.3 Release"
+git push origin_ssh v3.3.3
+# Make sure to run the performance tests for the new release and to update the graphs!
diff --git a/requirements-dev.txt b/requirements-dev.txt
index c298a0b5e..5947ce5dc 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,5 +1,12 @@
-pytest>=3.2.5
-pylama
-tox
-pysnmp
+black==21.6b0
+mypy==0.902
+mypy-extensions==0.4.3
+PyYAML==5.4
+pytest==6.2.5
+pylama==7.7.1
+twine==1.13.0
+pysnmp==4.4.12
+types-paramiko
+types-PyYAML
-r requirements.txt
+-r requirements-ttp.txt
diff --git a/requirements-genie.txt b/requirements-genie.txt
new file mode 100644
index 000000000..2e55f1ba6
--- /dev/null
+++ b/requirements-genie.txt
@@ -0,0 +1,2 @@
+pyats==22.2
+genie==22.2
diff --git a/requirements-ttp.txt b/requirements-ttp.txt
new file mode 100644
index 000000000..806325661
--- /dev/null
+++ b/requirements-ttp.txt
@@ -0,0 +1 @@
+ttp>=0.4.0
diff --git a/requirements.txt b/requirements.txt
index 0a7f52f20..cd8c47d3d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,3 @@
-paramiko>=2.0.0
-scp>=0.10.0
-pyyaml
-pyserial
-textfsm
+--index-url https://pypi.python.org/simple/
+
+-e .
diff --git a/setup.cfg b/setup.cfg
index 8ba5463ba..14abcad89 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,47 @@
+[bdist_wheel]
+universal = 0
+
+[metadata]
+license_file = LICENSE
+
[pylama]
linters = mccabe,pep8,pyflakes
ignore = D203,C901
-skip = tests/*,build/*,.tox/*,netmiko/_textfsm/*
+skip = build/*,.tox/*,netmiko/,examples/use_cases/*,.venv/*
[pylama:pep8]
max_line_length = 100
+
+[tool:pytest]
+addopts = -rs
+
+[mypy]
+# The mypy configurations: http://bit.ly/2zEl9WI
+python_version = 3.6
+check_untyped_defs = True
+disallow_any_generics = True
+disallow_untyped_calls = True
+disallow_untyped_defs = True
+disallow_incomplete_defs = True
+disallow_untyped_decorators = True
+ignore_errors = False
+ignore_missing_imports = True
+strict_optional = True
+warn_unused_configs = True
+warn_unused_ignores = True
+warn_return_any = True
+warn_redundant_casts = True
+
+[mypy-netmiko.base_connection]
+# CI-CD (GitHub actions was giving me errors on the two type: ignore lines
+# in base_connection.py associated with Tenacity.
+warn_unused_ignores = False
+
+[mypy-netmiko.cli_tools.netmiko_grep]
+ignore_errors = True
+
+[mypy-netmiko.cli_tools.netmiko_cfg]
+ignore_errors = True
+
+[mypy-netmiko.cli_tools.netmiko_show]
+ignore_errors = True
diff --git a/setup.py b/setup.py
index 6330dd553..3440c1bf7 100644
--- a/setup.py
+++ b/setup.py
@@ -4,6 +4,10 @@
import re
+with open("README.md", "r") as fs:
+ long_description = fs.read()
+
+
def find_version(*file_paths):
"""
This pattern was modeled on a method from the Python Packaging User Guide:
@@ -15,33 +19,49 @@ def find_version(*file_paths):
base_module_file = os.path.join(*file_paths)
with open(base_module_file) as f:
base_module_data = f.read()
- version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
- base_module_data, re.M)
+ version_match = re.search(
+ r"^__version__ = ['\"]([^'\"]*)['\"]", base_module_data, re.M
+ )
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
setup(
- name='netmiko',
- version=find_version('netmiko', '__init__.py'),
- description='Multi-vendor library to simplify Paramiko SSH connections to network devices',
- url='https://github.com/ktbyers/netmiko',
- author='Kirk Byers',
- author_email='ktbyers@twb-tech.com',
- license='MIT',
+ name="netmiko",
+ version=find_version("netmiko", "__init__.py"),
+ description="Multi-vendor library to simplify legacy CLI connections to network devices",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ url="https://github.com/ktbyers/netmiko",
+ author="Kirk Byers",
+ author_email="ktbyers@twb-tech.com",
+ license="MIT",
classifiers=[
- 'Development Status :: 4 - Beta',
- 'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ ],
+ packages=find_packages(exclude=("test*",)),
+ install_requires=[
+ "setuptools>=38.4.0",
+ "paramiko>=2.6.0",
+ "scp>=0.13.2",
+ "tenacity",
+ "textfsm>=1.1.2",
+ "ntc-templates>=2.0.0",
+ "pyserial",
+ "importlib_resources ; python_version<'3.7'",
],
- packages=find_packages(exclude=("test*", )),
- install_requires=['paramiko>=2.0.0', 'scp>=0.10.0', 'pyyaml', 'pyserial', 'textfsm'],
- extras_require={
- 'test': ['pytest>=3.2.5', ]
+ entry_points={
+ "console_scripts": [
+ "netmiko-grep = netmiko.cli_tools.netmiko_grep:main_ep",
+ "netmiko-show= netmiko.cli_tools.netmiko_show:main_ep",
+ "netmiko-cfg= netmiko.cli_tools.netmiko_cfg:main_ep",
+ ]
},
)
diff --git a/test.log b/test.log
new file mode 100644
index 000000000..62c13507b
--- /dev/null
+++ b/test.log
@@ -0,0 +1,129 @@
+DEBUG:paramiko.transport:starting thread (client mode): 0xb63946ec
+DEBUG:paramiko.transport:Local version/idstring: SSH-2.0-paramiko_2.4.1
+DEBUG:paramiko.transport:Remote version/idstring: SSH-2.0-Cisco-1.25
+INFO:paramiko.transport:Connected (version 2.0, client Cisco-1.25)
+DEBUG:paramiko.transport:kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-sha1', 'hmac-sha1-96', 'hmac-md5', 'hmac-md5-96'] server mac:['hmac-sha1', 'hmac-sha1-96', 'hmac-md5', 'hmac-md5-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
+DEBUG:paramiko.transport:Kex agreed: diffie-hellman-group-exchange-sha1
+DEBUG:paramiko.transport:HostKey agreed: ssh-rsa
+DEBUG:paramiko.transport:Cipher agreed: aes128-ctr
+DEBUG:paramiko.transport:MAC agreed: hmac-sha1
+DEBUG:paramiko.transport:Compression agreed: none
+DEBUG:paramiko.transport:Got server p (2048 bits)
+DEBUG:paramiko.transport:kex engine KexGex specified hash_algo
+DEBUG:paramiko.transport:Switch to new keys ...
+DEBUG:paramiko.transport:Adding ssh-rsa host key for cisco1.twb-tech.com: b'c77967d9e78b5c6d9acaaa55cc7ad897'
+DEBUG:paramiko.transport:userauth is OK
+INFO:paramiko.transport:Authentication (password) successful!
+DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
+DEBUG:paramiko.transport:[chan 0] Max packet out: 4096 bytes
+DEBUG:paramiko.transport:Secsh channel 0 opened.
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:netmiko:read_channel:
+pynet-rtr1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+pynet-rtr1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:In disable_paging
+DEBUG:netmiko:Command: terminal length 0
+
+DEBUG:netmiko:write_channel: b'terminal length 0\n'
+DEBUG:netmiko:Pattern is: pynet\-rtr1
+DEBUG:netmiko:_read_channel_expect read_data: ter
+DEBUG:netmiko:_read_channel_expect read_data: minal length 0
+pynet-rtr1#
+DEBUG:netmiko:Pattern found: pynet\-rtr1 terminal length 0
+pynet-rtr1#
+DEBUG:netmiko:terminal length 0
+pynet-rtr1#
+DEBUG:netmiko:Exiting disable_paging
+DEBUG:netmiko:write_channel: b'terminal width 511\n'
+DEBUG:netmiko:Pattern is: pynet\-rtr1
+DEBUG:netmiko:_read_channel_expect read_data: t
+DEBUG:netmiko:_read_channel_expect read_data: erminal width 511
+pynet-rtr1#
+DEBUG:netmiko:Pattern found: pynet\-rtr1 terminal width 511
+pynet-rtr1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+pynet-rtr1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+pynet-rtr1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:exit_config_mode:
+DEBUG:netmiko:write_channel: b'exit\n'
+DEBUG:paramiko.transport:starting thread (client mode): 0xfb54d3c8
+DEBUG:paramiko.transport:Local version/idstring: SSH-2.0-paramiko_2.7.1
+DEBUG:paramiko.transport:Remote version/idstring: SSH-2.0-Cisco-1.25
+INFO:paramiko.transport:Connected (version 2.0, client Cisco-1.25)
+DEBUG:paramiko.transport:kex algos:['diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa'] client encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-sha1', 'hmac-sha1-96'] server mac:['hmac-sha1', 'hmac-sha1-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
+DEBUG:paramiko.transport:Kex agreed: diffie-hellman-group-exchange-sha1
+DEBUG:paramiko.transport:HostKey agreed: ssh-rsa
+DEBUG:paramiko.transport:Cipher agreed: aes128-ctr
+DEBUG:paramiko.transport:MAC agreed: hmac-sha1
+DEBUG:paramiko.transport:Compression agreed: none
+DEBUG:paramiko.transport:Got server p (2048 bits)
+DEBUG:paramiko.transport:kex engine KexGex specified hash_algo
+DEBUG:paramiko.transport:Switch to new keys ...
+DEBUG:paramiko.transport:Adding ssh-rsa host key for cisco1.lasthop.io: b'539a8d09e0dab9e8f7ef2b61ba1d5805'
+DEBUG:paramiko.transport:userauth is OK
+INFO:paramiko.transport:Authentication (password) successful!
+DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes
+DEBUG:paramiko.transport:[chan 0] Max packet out: 4096 bytes
+DEBUG:paramiko.transport:Secsh channel 0 opened.
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:[find_prompt()]: prompt is cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:In disable_paging
+DEBUG:netmiko:Command: terminal length 0
+
+DEBUG:netmiko:write_channel: b'terminal length 0\n'
+DEBUG:netmiko:Pattern is: terminal\ length\ 0
+DEBUG:netmiko:_read_channel_expect read_data: t
+DEBUG:netmiko:_read_channel_expect read_data: erminal length 0
+cisco1#
+DEBUG:netmiko:Pattern found: terminal\ length\ 0 terminal length 0
+cisco1#
+DEBUG:netmiko:terminal length 0
+cisco1#
+DEBUG:netmiko:Exiting disable_paging
+DEBUG:netmiko:write_channel: b'terminal width 511\n'
+DEBUG:netmiko:Pattern is: terminal\ width\ 511
+DEBUG:netmiko:_read_channel_expect read_data: t
+DEBUG:netmiko:_read_channel_expect read_data: erminal width 511
+cisco1#
+DEBUG:netmiko:Pattern found: terminal\ width\ 511 terminal width 511
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:[find_prompt()]: prompt is cisco1#
+DEBUG:netmiko:write_channel: b'\n'
+DEBUG:netmiko:read_channel:
+cisco1#
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:read_channel:
+DEBUG:netmiko:write_channel: b'exit\n'
diff --git a/tests.sh b/tests.sh
new file mode 100755
index 000000000..08d93302b
--- /dev/null
+++ b/tests.sh
@@ -0,0 +1,8 @@
+black .
+pylama .
+mypy ./netmiko
+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
+py.test -v -s tests/unit/test_connection.py
diff --git a/tests/SLOG/cisco881_slog.log b/tests/SLOG/cisco881_slog.log
new file mode 100644
index 000000000..2e5125e58
--- /dev/null
+++ b/tests/SLOG/cisco881_slog.log
@@ -0,0 +1,14 @@
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+cisco1>show ip interface brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+cisco1>exit
diff --git a/tests/SLOG/cisco881_slog_append.log b/tests/SLOG/cisco881_slog_append.log
new file mode 100644
index 000000000..215ba1dd0
--- /dev/null
+++ b/tests/SLOG/cisco881_slog_append.log
@@ -0,0 +1,30 @@
+Initial file contents
+
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+cisco1>show ip interface brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+cisco1>exit
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+Testing password and secret replacement
+This is my password ********
+This is my secret ********
+
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+Testing unicode
+😁😁
\ No newline at end of file
diff --git a/tests/SLOG/cisco881_slog_append_compare.log b/tests/SLOG/cisco881_slog_append_compare.log
new file mode 100644
index 000000000..2e5125e58
--- /dev/null
+++ b/tests/SLOG/cisco881_slog_append_compare.log
@@ -0,0 +1,14 @@
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+cisco1>show ip interface brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+cisco1>exit
diff --git a/tests/SLOG/cisco881_slog_compare.log b/tests/SLOG/cisco881_slog_compare.log
new file mode 100644
index 000000000..2e5125e58
--- /dev/null
+++ b/tests/SLOG/cisco881_slog_compare.log
@@ -0,0 +1,14 @@
+cisco1>terminal width 511
+cisco1>terminal length 0
+cisco1>
+cisco1>
+cisco1>show ip interface brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+cisco1>exit
diff --git a/tests/SLOG/cisco881_slog_wr.log b/tests/SLOG/cisco881_slog_wr.log
new file mode 100644
index 000000000..ab3382ce1
--- /dev/null
+++ b/tests/SLOG/cisco881_slog_wr.log
@@ -0,0 +1,17 @@
+terminal width 511
+cisco1>terminal width 511
+cisco1>terminal length 0
+terminal length 0
+cisco1>
+
+cisco1>
+
+cisco1>enable
+enable
+Password: ********
+
+cisco1#
+
+cisco1#
+
+cisco1#exit
diff --git a/tests/SLOG/cisco881_slog_wr_compare.log b/tests/SLOG/cisco881_slog_wr_compare.log
new file mode 100644
index 000000000..caa2adc2e
--- /dev/null
+++ b/tests/SLOG/cisco881_slog_wr_compare.log
@@ -0,0 +1,27 @@
+terminal width 511
+cisco1>terminal width 511
+cisco1>terminal length 0
+terminal length 0
+cisco1>
+
+cisco1>
+
+cisco1>show foooooooo
+show foooooooo
+ ^
+% Invalid input detected at '^' marker.
+
+cisco1>
+
+cisco1>show ip interface brief
+show ip interface brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+
+cisco1>exit
diff --git a/tests/SLOG/netmiko.log b/tests/SLOG/netmiko.log
new file mode 100644
index 000000000..20345762d
--- /dev/null
+++ b/tests/SLOG/netmiko.log
@@ -0,0 +1,117 @@
+write_channel: b'\n'
+read_channel:
+read_channel:
+cisco1>
+Pattern found: (cisco1.*)
+cisco1>
+write_channel: b'enable\n'
+read_channel:
+read_channel: enable
+Password:
+Pattern found: (enable) enable
+read_channel:
+Pattern found: ((?:cisco1|ssword))
+Password
+write_channel: b'********\n'
+read_channel:
+read_channel:
+read_channel:
+cisco1#
+Pattern found: (cisco1) :
+cisco1
+write_channel: b'\n'
+read_channel:
+read_channel:
+cisco1#
+Pattern found: (cisco1.*) #
+cisco1#
+read_channel:
+write_channel: b'\n'
+read_channel:
+cisco1#
+read_channel:
+read_channel:
+write_channel: b'exit\n'
+write_channel: b'terminal width 511\n'
+read_channel:
+read_channel:
+cisco1>terminal width
+read_channel: 511
+cisco1>
+Pattern found: (terminal width 511)
+cisco1>terminal width 511
+In disable_paging
+Command: terminal length 0
+
+write_channel: b'terminal length 0\n'
+read_channel:
+read_channel: terminal lengt
+read_channel: h 0
+cisco1>
+Pattern found: (terminal\ length\ 0)
+cisco1>terminal length 0
+
+cisco1>terminal length 0
+Exiting disable_paging
+read_channel:
+Clear buffer detects data in the channel
+read_channel:
+write_channel: b'\n'
+read_channel:
+cisco1>
+read_channel:
+[find_prompt()]: prompt is cisco1>
+write_channel: b'terminal width 511\n'
+read_channel:
+read_channel: cisco1>terminal width
+read_channel: 511
+cisco1>
+Pattern found: (terminal width 511) cisco1>terminal width 511
+In disable_paging
+Command: terminal length 0
+
+write_channel: b'terminal length 0\n'
+read_channel:
+read_channel: terminal lengt
+read_channel: h 0
+cisco1>
+Pattern found: (terminal\ length\ 0)
+cisco1>terminal length 0
+
+cisco1>terminal length 0
+Exiting disable_paging
+read_channel:
+Clear buffer detects data in the channel
+read_channel:
+write_channel: b'\n'
+read_channel:
+cisco1>
+read_channel:
+[find_prompt()]: prompt is cisco1>
+read_channel:
+read_channel:
+write_channel: b'\n'
+read_channel:
+cisco1>
+read_channel:
+[find_prompt()]: prompt is cisco1>
+write_channel: b'show ip interface brief\n'
+read_channel:
+read_channel: show ip interf
+read_channel: ace brief
+Interface IP-Address OK? Method Status Protocol
+FastEthernet0 unassigned YES unset down down
+FastEthernet1 unassigned YES unset down down
+FastEthernet2 unassigned YES unset down down
+FastEthernet3 unassigned YES unset down down
+FastEthernet4 10.220.88.20 YES NVRAM up up
+Vlan1 unassigned YES unset down down
+cisco1>
+Pattern found: (show\ ip\ interface\ brief) show ip interface brief
+read_channel:
+write_channel: b'\n'
+read_channel:
+cisco1>
+read_channel:
+read_channel:
+write_channel: b'exit\n'
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
diff --git a/tests/cisco_s300_commands.txt b/tests/cisco_s300_commands.txt
deleted file mode 100644
index ae799faa2..000000000
--- a/tests/cisco_s300_commands.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-logging buffered notifications
-logging buffered warnings
-no logging console
diff --git a/tests/conftest.py b/tests/conftest.py
index 7baa85f32..d451a7aad 100755
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -6,7 +6,7 @@
import pytest
from netmiko import ConnectHandler, FileTransfer, InLineTransfer, SSHDetect
-from tests.test_utils import parse_yaml
+from test_utils import parse_yaml
PWD = path.dirname(path.realpath(__file__))
@@ -14,20 +14,61 @@
def pytest_addoption(parser):
"""Add test_device option to py.test invocations."""
- parser.addoption("--test_device", action="store", dest="test_device", type=str,
- help="Specify the platform type to test on")
+ parser.addoption(
+ "--test_device",
+ action="store",
+ dest="test_device",
+ type=str,
+ help="Specify the platform type to test on",
+ )
-@pytest.fixture(scope='module')
+
+@pytest.fixture(scope="module")
def net_connect(request):
"""
Create the SSH connection to the remote device
Return the netmiko connection object
"""
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
+ test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
+ device = test_devices[device_under_test]
+ device["verbose"] = False
+ conn = ConnectHandler(**device)
+ return conn
+
+
+@pytest.fixture(scope="module")
+def net_connect_cmd_verify(request):
+ """
+ Create the SSH connection to the remote device
+
+ Return the netmiko connection object
+
+ Set global_cmd_verify = False
+ """
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
+ device["fast_cli"] = False
+ device["global_cmd_verify"] = False
+ conn = ConnectHandler(**device)
+ return conn
+
+
+@pytest.fixture(scope="function")
+def net_connect_newconn(request):
+ """
+ Create the SSH connection to the remote device
+
+ Return the netmiko connection object.
+ Force a new connection for each test.
+ """
+ device_under_test = request.config.getoption("test_device")
+ test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
+ device = test_devices[device_under_test]
+ device["verbose"] = False
conn = ConnectHandler(**device)
return conn
@@ -35,42 +76,84 @@ def net_connect(request):
@pytest.fixture()
def net_connect_cm(request):
"""
- Create the SSH connection to the remote device using a context manager
+ Create the SSH connection to the remote device using a context manager
retrieve the find_prompt() data and close the connection.
"""
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
my_prompt = ""
with ConnectHandler(**device) as conn:
my_prompt = conn.find_prompt()
return my_prompt
-@pytest.fixture(scope='module')
+@pytest.fixture(scope="function")
+def net_connect_slog_wr(request):
+ """
+ Create the SSH connection to the remote device. Modify session_log init arguments.
+
+ Return the netmiko connection object.
+ """
+ device_under_test = request.config.getoption("test_device")
+ test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
+ device = test_devices[device_under_test]
+ device["verbose"] = False
+ # Overwrite default session_log location
+ device["session_log"] = "SLOG/cisco881_slog_wr.log"
+ device["session_log_record_writes"] = True
+ conn = ConnectHandler(**device)
+ return conn
+
+
+@pytest.fixture(scope="module")
+def device_slog(request):
+ """
+ Create the SSH connection to the remote device. Modify session_log init arguments.
+
+ Return the netmiko device (not connected)
+ """
+ device_under_test = request.config.getoption("test_device")
+ test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
+ device = test_devices[device_under_test]
+ # Fictional secret
+ device["secret"] = "invalid"
+ device["verbose"] = False
+ device["session_log_file_mode"] = "append"
+ return device
+
+
+@pytest.fixture(scope="module")
def expected_responses(request):
- '''
+ """
Parse the responses.yml file to get a responses dictionary
- '''
- device_under_test = request.config.getoption('test_device')
+ """
+ device_under_test = request.config.getoption("test_device")
responses = parse_yaml(PWD + "/etc/responses.yml")
return responses[device_under_test]
-@pytest.fixture(scope='module')
+@pytest.fixture(scope="module")
def commands(request):
- '''
+ """
Parse the commands.yml file to get a commands dictionary
- '''
- device_under_test = request.config.getoption('test_device')
+ """
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- test_platform = device['device_type']
+ test_platform = device["device_type"]
commands_yml = parse_yaml(PWD + "/etc/commands.yml")
+
+ # Nokia SR-OS driver is overloaded with both classical-CLI and MD-CLI
+ # Swap out the commands to be the MD-CLI commands
+ if device_under_test == "sros1_md":
+ test_platform = "nokia_sros_md"
+
return commands_yml[test_platform]
+
def delete_file_nxos(ssh_conn, dest_file_system, dest_file):
"""
nxos1# delete bootflash:test2.txt
@@ -84,36 +167,84 @@ def delete_file_nxos(ssh_conn, dest_file_system, dest_file):
full_file_name = "{}{}".format(dest_file_system, dest_file)
cmd = "delete {}".format(full_file_name)
- output = ssh_conn.send_command_timing(cmd)
- if 'yes/no/abort' in output and dest_file in output:
- output += ssh_conn.send_command_timing("y", strip_command=False, strip_prompt=False)
+ output = ssh_conn.send_command(cmd, expect_string=r"Do you want to delete")
+ if "yes/no/abort" in output and dest_file in output:
+ output += ssh_conn.send_command(
+ "y", expect_string=r"#", strip_command=False, strip_prompt=False
+ )
return output
else:
output += ssh_conn.send_command_timing("abort")
raise ValueError("An error happened deleting file on Cisco NX-OS")
+
+def delete_file_xr(ssh_conn, dest_file_system, dest_file):
+ """
+ Delete a remote file for a Cisco IOS-XR device:
+
+ delete disk0:/test9.txt
+ Mon Aug 31 17:56:15.008 UTC
+ Delete disk0:/test9.txt[confirm]
+ """
+ if not dest_file_system:
+ raise ValueError("Invalid file system specified")
+ if not dest_file:
+ raise ValueError("Invalid dest file specified")
+
+ full_file_name = f"{dest_file_system}/{dest_file}"
+
+ cmd = f"delete {full_file_name}"
+ output = ssh_conn.send_command(cmd, expect_string=r"Delete.*confirm")
+ if "Delete" in output and dest_file in output:
+ output += ssh_conn.send_command("\n", expect_string=r"#")
+ return output
+
+ raise ValueError("An error happened deleting file on Cisco IOS-XR")
+
+
def delete_file_ios(ssh_conn, dest_file_system, dest_file):
- """Delete a remote file for a Cisco IOS device."""
+ """
+ Delete a remote file for a Cisco IOS device:
+
+ cisco1#del flash:/useless_file.cfg
+ Delete filename [useless_file.cfg]?
+ Delete flash:/useless_file.cfg? [confirm]y
+
+ delete disk0:/test9.txt
+ Mon Aug 31 17:56:15.008 UTC
+ Delete disk0:/test9.txt[confirm]
+ """
if not dest_file_system:
raise ValueError("Invalid file system specified")
if not dest_file:
raise ValueError("Invalid dest file specified")
- full_file_name = "{0}/{1}".format(dest_file_system, dest_file)
+ full_file_name = f"{dest_file_system}/{dest_file}"
- cmd = "delete {0}".format(full_file_name)
- output = ssh_conn.send_command_timing(cmd)
- if 'Delete' in output and dest_file in output:
- output += ssh_conn.send_command_timing("\n")
- if 'Delete' in output and full_file_name in output and 'confirm' in output:
- output += ssh_conn.send_command_timing("y")
- return output
- else:
- output += ssh_conn.send_command_timing("n")
+ cmd = f"delete {full_file_name}"
+ output = ssh_conn.send_command(cmd, expect_string=r"Delete filename")
+ if "Delete" in output and dest_file in output:
+ output += ssh_conn.send_command("\n", expect_string=r"confirm")
+ output += ssh_conn.send_command("y", expect_string=r"#")
+ return output
raise ValueError("An error happened deleting file on Cisco IOS")
+def delete_file_dellos10(ssh_conn, dest_file_system, dest_file):
+ """Delete a remote file for a Dell OS10 device."""
+ if not dest_file:
+ raise ValueError("Invalid dest file specified")
+
+ cmd = "delete home://{}".format(dest_file)
+ output = ssh_conn.send_command_timing(cmd)
+ if "Proceed to delete" in output:
+ output = ssh_conn.send_command_timing("yes")
+ return output
+
+ raise ValueError("An error happened deleting file on Dell OS10")
+
+
def delete_file_generic(ssh_conn, dest_file_system, dest_file):
"""Delete a remote file for a Junos device."""
full_file_name = "{}/{}".format(dest_file_system, dest_file)
@@ -124,7 +255,37 @@ def delete_file_generic(ssh_conn, dest_file_system, dest_file):
return output
-@pytest.fixture(scope='module')
+def delete_file_ciena_saos(ssh_conn, dest_file_system, dest_file):
+ """Delete a remote file for a ciena device."""
+ full_file_name = "{}/{}".format(dest_file_system, dest_file)
+ cmd = "file rm {}".format(full_file_name)
+ output = ssh_conn.send_command_timing(cmd, strip_command=False, strip_prompt=False)
+ return output
+
+
+def delete_file_nokia_sros(ssh_conn, dest_file_system, dest_file):
+ """Delete a remote file for a Nokia SR OS device."""
+ full_file_name = "{}/{}".format(dest_file_system, dest_file)
+ cmd = "file delete {} force".format(full_file_name)
+ cmd_prefix = ""
+ if "@" in ssh_conn.base_prompt:
+ cmd_prefix = "//"
+ ssh_conn.send_command(cmd_prefix + "environment no more")
+ output = ssh_conn.send_command_timing(
+ cmd_prefix + cmd, strip_command=False, strip_prompt=False
+ )
+ return output
+
+
+def delete_file_extreme_exos(ssh_conn, dest_file_system, dest_file):
+ """Delete a remote file for an Extreme EXOS device."""
+ full_file_name = "{}/{}".format(dest_file_system, dest_file)
+ cmd = "rm {}".format(full_file_name)
+ output = ssh_conn.send_command_timing(cmd, strip_command=False, strip_prompt=False)
+ return output
+
+
+@pytest.fixture(scope="module")
def scp_fixture(request):
"""
Create an FileTransfer object.
@@ -143,36 +304,45 @@ def scp_fixture(request):
f.write("no logging console\n")
f.write("logging buffered 10000\n")
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
ssh_conn = ConnectHandler(**device)
- platform = device['device_type']
- dest_file_system = platform_args[platform]['file_system']
- source_file = 'test9.txt'
- dest_file = 'test9.txt'
- local_file = 'testx.txt'
- direction = 'put'
-
- scp_transfer = FileTransfer(ssh_conn, source_file=source_file, dest_file=dest_file,
- file_system=dest_file_system, direction=direction)
+ platform = device["device_type"]
+ dest_file_system = platform_args[platform]["file_system"]
+ if "ciena_saos" in platform and ssh_conn.username:
+ dest_file_system = f"/tmp/users/{ssh_conn.username}"
+
+ source_file = "test9.txt"
+ dest_file = "test9.txt"
+ local_file = f"test_{platform}/testx.txt"
+ direction = "put"
+
+ scp_transfer = FileTransfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=dest_file_system,
+ direction=direction,
+ )
scp_transfer.establish_scp_conn()
# Make sure SCP is enabled
- if platform_args[platform]['enable_scp']:
+ if platform_args[platform]["enable_scp"]:
scp_transfer.enable_scp()
# Delete the test transfer files
if scp_transfer.check_file_exists():
- func = platform_args[platform]['delete_file']
+ func = platform_args[platform]["delete_file"]
func(ssh_conn, dest_file_system, dest_file)
if os.path.exists(local_file):
os.remove(local_file)
return (ssh_conn, scp_transfer)
-@pytest.fixture(scope='module')
+
+@pytest.fixture(scope="module")
def scp_fixture_get(request):
"""
Create an FileTransfer object (direction=get)
@@ -180,25 +350,30 @@ def scp_fixture_get(request):
Return a tuple (ssh_conn, scp_handle)
"""
platform_args = get_platform_args()
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
ssh_conn = ConnectHandler(**device)
- platform = device['device_type']
- dest_file_system = platform_args[platform]['file_system']
- source_file = 'test9.txt'
- local_file = 'testx.txt'
+ platform = device["device_type"]
+ dest_file_system = platform_args[platform]["file_system"]
+ source_file = "test9.txt"
+ local_file = f"test_{platform}/testx.txt"
dest_file = local_file
- direction = 'get'
-
- scp_transfer = FileTransfer(ssh_conn, source_file=source_file, dest_file=dest_file,
- file_system=dest_file_system, direction=direction)
+ direction = "get"
+
+ scp_transfer = FileTransfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=dest_file_system,
+ direction=direction,
+ )
scp_transfer.establish_scp_conn()
# Make sure SCP is enabled
- if platform_args[platform]['enable_scp']:
+ if platform_args[platform]["enable_scp"]:
scp_transfer.enable_scp()
# Delete the test transfer files
@@ -206,7 +381,8 @@ def scp_fixture_get(request):
os.remove(local_file)
return (ssh_conn, scp_transfer)
-@pytest.fixture(scope='module')
+
+@pytest.fixture(scope="module")
def tcl_fixture(request):
"""
Create an InLineTransfer object.
@@ -218,20 +394,26 @@ def tcl_fixture(request):
# Not important what it is in the file
f.write("no logging console\n")
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
+ platform = device["device_type"]
ssh_conn = ConnectHandler(**device)
- dest_file_system = 'flash:'
- source_file = 'test9.txt'
- dest_file = 'test9.txt'
- local_file = 'testx.txt'
- direction = 'put'
+ dest_file_system = "flash:"
+ source_file = "test9.txt"
+ dest_file = "test9.txt"
+ local_file = f"test_{platform}/testx.txt"
+ direction = "put"
- tcl_transfer = InLineTransfer(ssh_conn, source_file=source_file, dest_file=dest_file,
- file_system=dest_file_system, direction=direction)
+ tcl_transfer = InLineTransfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=dest_file_system,
+ direction=direction,
+ )
# Delete the test transfer files
if tcl_transfer.check_file_exists():
@@ -241,22 +423,24 @@ def tcl_fixture(request):
return (ssh_conn, tcl_transfer)
-@pytest.fixture(scope='module')
+
+@pytest.fixture(scope="module")
def ssh_autodetect(request):
- """Create an SSH autodetect object.
+ """Create an SSH autodetect object.
return (ssh_conn, real_device_type)
"""
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
- my_device_type = device.pop('device_type')
- device['device_type'] = 'autodetect'
+ device["verbose"] = False
+ my_device_type = device.pop("device_type")
+ device["device_type"] = "autodetect"
conn = SSHDetect(**device)
return (conn, my_device_type)
-@pytest.fixture(scope='module')
+
+@pytest.fixture(scope="module")
def scp_file_transfer(request):
"""
Testing file_transfer
@@ -275,67 +459,103 @@ def scp_file_transfer(request):
f.write("no logging console\n")
f.write("logging buffered 10000\n")
- device_under_test = request.config.getoption('test_device')
+ device_under_test = request.config.getoption("test_device")
test_devices = parse_yaml(PWD + "/etc/test_devices.yml")
device = test_devices[device_under_test]
- device['verbose'] = False
+ device["verbose"] = False
ssh_conn = ConnectHandler(**device)
- platform = device['device_type']
- file_system = platform_args[platform]['file_system']
- source_file = 'test9.txt'
- dest_file = 'test9.txt'
- local_file = 'testx.txt'
- alt_file = 'test2.txt'
- direction = 'put'
-
- scp_transfer = FileTransfer(ssh_conn, source_file=source_file, dest_file=dest_file,
- file_system=file_system, direction=direction)
+ platform = device["device_type"]
+ file_system = platform_args[platform]["file_system"]
+ source_file = "test9.txt"
+ dest_file = "test9.txt"
+ local_file = f"test_{platform}/testx.txt"
+ alt_file = "test2.txt"
+ direction = "put"
+
+ scp_transfer = FileTransfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ )
scp_transfer.establish_scp_conn()
# Delete the test transfer files
if scp_transfer.check_file_exists():
- func = platform_args[platform]['delete_file']
+ func = platform_args[platform]["delete_file"]
func(ssh_conn, file_system, dest_file)
if os.path.exists(local_file):
os.remove(local_file)
if os.path.exists(alt_file):
os.remove(alt_file)
+ scp_transfer.close_scp_chan()
+
return (ssh_conn, file_system)
+
def get_platform_args():
return {
- 'cisco_ios': {
- 'file_system': 'flash:',
- 'enable_scp': True,
- 'delete_file': delete_file_ios,
+ "cisco_ios": {
+ "file_system": "flash:",
+ "enable_scp": True,
+ "delete_file": delete_file_ios,
+ },
+ "cisco_xe": {
+ "file_system": "flash:",
+ "enable_scp": True,
+ "delete_file": delete_file_ios,
},
- 'juniper_junos': {
- 'file_system': '/var/tmp',
- 'enable_scp': False,
- 'delete_file': delete_file_generic,
+ "cisco_asa": {
+ "file_system": "flash:",
+ "enable_scp": False,
+ "delete_file": delete_file_ios,
},
- 'arista_eos': {
- 'file_system': '/mnt/flash',
- 'enable_scp': False,
- 'delete_file': delete_file_generic,
+ "juniper_junos": {
+ "file_system": "/var/tmp",
+ "enable_scp": False,
+ "delete_file": delete_file_generic,
},
- 'cisco_nxos': {
- 'file_system': 'bootflash:',
- 'enable_scp': False,
- 'delete_file': delete_file_nxos,
+ "arista_eos": {
+ "file_system": "/mnt/flash",
+ "enable_scp": False,
+ "delete_file": delete_file_generic,
},
- 'cisco_xr': {
- 'file_system': 'disk0:',
- 'enable_scp': False,
- # Delete pattern is the same on IOS-XR
- 'delete_file': delete_file_ios,
+ "cisco_nxos": {
+ "file_system": "bootflash:",
+ "enable_scp": False,
+ "delete_file": delete_file_nxos,
},
- 'linux': {
- 'file_system': '/var/tmp',
- 'enable_scp': False,
- 'delete_file': delete_file_generic,
+ "cisco_xr": {
+ "file_system": "disk0:",
+ "enable_scp": False,
+ "delete_file": delete_file_xr,
+ },
+ "linux": {
+ "file_system": "/var/tmp",
+ "enable_scp": False,
+ "delete_file": delete_file_generic,
+ },
+ "dellos10": {
+ "file_system": "/home/admin",
+ "enable_scp": False,
+ "delete_file": delete_file_dellos10,
+ },
+ "ciena_saos": {
+ "file_system": "/tmp/users/ciena",
+ "enable_scp": False,
+ "delete_file": delete_file_ciena_saos,
+ },
+ "nokia_sros": {
+ "file_system": "cf3:",
+ "enable_scp": False,
+ "delete_file": delete_file_nokia_sros,
+ },
+ "extreme_exos": {
+ "file_system": "/usr/local/cfg",
+ "enable_scp": False,
+ "delete_file": delete_file_extreme_exos,
},
}
-
diff --git a/tests/etc/.netmiko.yml b/tests/etc/.netmiko.yml
new file mode 100644
index 000000000..1d7e0ab28
--- /dev/null
+++ b/tests/etc/.netmiko.yml
@@ -0,0 +1,18 @@
+---
+rtr1:
+ device_type: cisco_ios
+ ip: 10.10.10.1
+ username: admin
+ password: cisco123
+ secret: cisco123
+
+rtr2:
+ device_type: cisco_ios
+ ip: 10.10.10.2
+ username: admin
+ password: cisco123
+ secret: cisco123
+
+cisco:
+ - rtr1
+ - rtr2
diff --git a/tests/etc/cisco_ios_show_version.template b/tests/etc/cisco_ios_show_version.template
new file mode 100644
index 000000000..13a04ba49
--- /dev/null
+++ b/tests/etc/cisco_ios_show_version.template
@@ -0,0 +1,4 @@
+Value Model (\S+)
+
+Start
+ ^Cisco IOS Software, Catalyst ${Model}
diff --git a/tests/etc/commands.yml.example b/tests/etc/commands.yml.example
index e3ef91cb1..c3cd94cb9 100644
--- a/tests/etc/commands.yml.example
+++ b/tests/etc/commands.yml.example
@@ -3,17 +3,62 @@
cisco_ios:
version: "show version"
basic: "show ip interface brief"
+ wide_command: "show ip access-lists myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
extended_output: "show version" # requires paging to be disabled
- config:
+ config:
+ - "logging buffered 20000" # base command
+ - "no logging console"
+ - "logging buffered 20010" # something you can verify has changed
+ config_verification: "show run | inc logging buffer"
+ config_file: "cisco_ios_commands.txt"
+ save_config_confirm: False
+
+cisco_ios_telnet:
+ version: "show version"
+ basic: "show ip interface brief"
+ wide_command: "show ip access-lists myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
+ extended_output: "show version" # requires paging to be disabled
+ config:
- "logging buffered 20000" # base command
- "no logging console"
- "logging buffered 20010" # something you can verify has changed
config_verification: "show run | inc logging buffer"
config_file: "cisco_ios_commands.txt"
+ save_config_confirm: False
+
+cisco_xr:
+ version: "show version"
+ basic: "show ip interface brief"
+ basic_textfsm: "show interface brief"
+ wide_command: "show access-list myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
+ extended_output: "show version" # requires paging to be disabled
+ config:
+ - "logging buffered 4000000" # base command
+ - "no logging console"
+ - "logging buffered 4000010" # something you can verify has changed
+ config_verification: "show run | inc logging buffer"
+ support_commit: True
+ commit_verification: "show configuration commit list 1 detail"
+
+cisco_s300:
+ version: "show version"
+ basic: "show ip interface"
+ wide_command: "show ip access-lists myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
+ extended_output: "show run" # requires paging to be disabled
+ config:
+ - 'logging buffered notifications'
+ - 'no logging console'
+ - 'logging buffered warnings'
+ config_verification: "show run"
+ config_file: "cisco_ios_commands.txt"
+ save_config_confirm: True
+ save_config_response: ''
cisco_asa:
version: "show version"
basic: "show ip"
+ wide_command: "show access-list myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
+ basic_textfsm: "show route"
extended_output: "show version" # requires paging to be disabled
config:
- 'logging buffered notifications'
@@ -25,8 +70,9 @@ cisco_asa:
arista_eos:
version: "show version"
basic: "show ip int brief"
+ wide_command: "show ip access-lists myverybiglongaccesslistthatdoesntexistandwherethisexceeds80characterssolinewrappingoccurs"
extended_output: "show logging" # requires paging to be disabled
- config:
+ config:
- "logging buffered 20000"
- "no logging console"
- "logging buffered 20010"
@@ -35,18 +81,30 @@ arista_eos:
hp_procurve:
version: "show version"
basic: "show ip"
+ basic_textfsm: "show system"
extended_output: "show logging" # requires paging to be disabled
- config:
+ config:
- 'time timezone -420'
- 'time daylight-time-rule Continental-US-and-Canada'
- 'time timezone -480'
- config_verification: "show run"
+ config_verification: "show run"
+
+hp_comware:
+ version: "display version"
+ basic: "display ip int brief"
+ extended_output: "display version" # requires paging to be disabled
+ config:
+ - 'ip host test1 1.1.1.1'
+ - 'undo ip host test1 1.1.1.1'
+ - 'ip host test1 1.1.1.2'
+ config_verification: "display current-configuration"
-juniper:
+juniper_junos:
version: "show version"
basic: "show interfaces terse"
+ basic_textfsm: "show interfaces"
extended_output: "show configuration" # requires paging to be disabled
- config:
+ config:
- 'set system syslog archive size 110k files 3'
- 'set system time-zone America/New_York'
- 'set system syslog archive size 120k files 3'
@@ -55,6 +113,54 @@ juniper:
rollback: 'rollback 0'
commit_verification: "run show system commit"
+linux:
+ version: "uname -a"
+ basic: "ifconfig -a | grep inet | grep -v inet6 "
+ wide_command: 'echo "cable modem deny 0015.f2fe.ba11"; echo "cable modem deny 0015.f2fe.ba12"; echo "cable modem deny 0015.f2fe.ba13"'
+ extended_output: "netstat -an" # requires paging to be disabled
+ # config_long_command: "ls verylongcommandnamethatwillcauselinewrapissuesasitdoesnotfitonesinglescreengreaterthan127charsandthensomesothingsreallyarennotright"
+ # config_verification: "ls"
+
+dell_force10:
+ version: "show version"
+ basic: "show ip interface brief managementethernet 0/0"
+ extended_output: "show ip interface brief" # requires paging to be disabled
+ config:
+ - "logging buffered 50000" # base command
+ - "no logging console"
+ - "logging buffered 50010" # something you can verify has changed
+ config_verification: "show run"
+
+cisco_nxos:
+ version: "show version"
+ basic: "show ip interface brief vrf management"
+ basic_textfsm: "show interface brief"
+ extended_output: "show logging" # requires paging to be disabled
+ config:
+ - "logging console 0" # base command
+ - "no logging console"
+ - "logging console 4" # something you can verify has changed
+ config_verification: "show run | inc logging"
+ config_long_command: "snmp-server location verylongsnmplocationnamethatwillcauselinewrapissuesasitdoesnotfitonesinglescreengreaterthan127charsandthensomesothingsreallyarennotright"
+
+cisco_xe:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show version" # requires paging to be disabled
+ config:
+ - "logging buffered 20000" # base command
+ - "no logging console"
+ - "logging buffered 20010" # something you can verify has changed
+ config_verification: "show run | inc logging buffer"
+
+juniper_screenos:
+ version: "get system version"
+ basic: "get route"
+ extended_output: "get config" # requires paging to be disabled
+ config:
+ - 'set alias test "test"'
+ config_verification: "get config | inc alias"
+
fortinet:
version: "get system status"
basic: "get system interface physical"
@@ -126,6 +232,34 @@ ubiquiti_edge:
- "logging persistent 4"
config_verification: "show running-config | include 'logging'"
+ubiquiti_unifiswitch:
+ version: "show version"
+ basic: "show network"
+ extended_output: "show running-config"
+ config:
+ - "logging persistent 3"
+ - "no logging persistent"
+ - "logging persistent 4"
+ config_verification: "show running-config | include 'logging'"
+
+dellos10:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show running-config"
+ config:
+ - "host-description test"
+ - "no host-description"
+ - "host-description node"
+ config_verification: "show running-config"
+
+dell_sonic:
+ version: "show version"
+ basic: "show ip interfaces"
+ extended_output: "show running-configuration"
+ config:
+ - "interface Vlan100"
+ config_verification: "show running-configuration"
+
dell_powerconnect:
version: "show version"
basic: "show ip interface vlan 1"
@@ -154,6 +288,11 @@ alcatel_aos:
- 'VLAN 666'
config_verification: "show vlan"
+netscaler:
+ version: "show version"
+ basic: "show ip -summary"
+ extended_output: "show interfaces"
+
calix_b6_ssh:
version: "show version"
basic: "show interface bvi 1"
@@ -164,3 +303,199 @@ calix_b6_ssh:
- "access-list ethernet 999 permit ip"
- "access-list ethernet 999 permit arp"
config_verification: "find running-config 999"
+
+ipinfusion_ocnos:
+ version: "show version"
+ basic: "show ip interface eth0 brief"
+ extended_output: "show ip interface brief" # requires paging to be disabled
+ config:
+ - "logging level ospf 4" # base command
+ - "no logging level ospf"
+ - "logging level ospf 5" # something you can verify has changed
+ config_verification: "show logging level ospf"
+ save_config_cmd: 'write'
+ save_config_confirm: False
+ save_config_response: "[OK]"
+
+ipinfusion_ocnos_telnet:
+ version: "show version"
+ basic: "show ip interface eth0 brief"
+ extended_output: "show ip interface brief" # requires paging to be disabled
+ config:
+ - "logging level ospf 4" # base command
+ - "no logging level ospf"
+ - "logging level ospf 5" # something you can verify has changed
+ config_verification: "show logging level ospf"
+ save_config_cmd: 'write'
+ save_config_confirm: False
+ save_config_response: "[OK]"
+
+oneaccess_oneos:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show system status" # requires paging to be disabled
+ config:
+ - "logging buffered size 20000" # base command
+ - "no logging console"
+ - "logging buffered size 20010" # something you can verify has changed
+ config_verification: "show run | inc logging buffer"
+ save_config_cmd: 'write'
+ save_config_confirm: False
+ save_config_response: "[OK]"
+
+oneaccess_oneos_telnet:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show system status" # requires paging to be disabled
+ config:
+ - "logging buffered size 20000" # base command
+ - "no logging console"
+ - "logging buffered size 20010" # something you can verify has changed
+ config_verification: "show run | inc logging buffer"
+ save_config_cmd: 'write'
+ save_config_confirm: False
+ save_config_response: "[OK]"
+
+mikrotik_routeros:
+ version: "/system resource print"
+ basic: "/ip address print"
+ extended_output: "/interface print oid"
+ config:
+ - "/ip upnp interfaces remove numbers=0" # base command
+ - "/ip upnp interfaces add interface=bridge1 type=external"
+ - "/ip upnp interfaces add interface=bridge1 type=external"
+ config_verification: '/ip upnp interfaces print'
+ save_config_confirm: False
+ save_config_response: ">"
+
+cloudgenix_ion:
+ version: "dump software status"
+ basic: "dump interface status 1"
+ extended_output: "inspect interface stats all"
+ config:
+ - "config interface 2 ip static address=172.16.16.15/24 gw=172.16.16.1 dns=8.8.8.8"
+ - "config interface 2 ip static address=172.16.16.16/24 gw=172.16.16.1 dns=8.8.8.8"
+ config_verification: "dump interface status 2"
+ save_config_confirm: False
+ save_config_response: "#"
+
+keymile:
+ version: "show version"
+ basic: "get /cfgm/IP_Address"
+ extended_output: "ls"
+
+keymile_nos:
+ version: "show version"
+ basic: "show ip interface brief | include br328"
+ extended_output: "show interface"
+ config:
+ - "log login enable"
+ config_verification: "show running-config | include log"
+ save_config_cmd: 'write memory'
+ save_config_confirm: True
+ save_config_response: '[OK]'
+
+dlink_ds:
+ version: "show greeting_message"
+ basic: "show ipif"
+ config:
+ - enable command logging
+ config_verification: "show config current_config include \"logging\""
+ extended_output: "show config current_config" # requires paging to be disabled
+
+dlink_ds_telnet:
+ version: "show greeting_message"
+ basic: "show ipif"
+ config:
+ - enable command logging
+ config_verification: "show config current_config include \"logging\""
+ extended_output: "show config current_config" # requires paging to be disabled
+
+ruijie_os:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show version"
+ config:
+ - "logging buffered 20000"
+ - "no logging console"
+ - "logging buffered 20010"
+ config_verification: "show run | inc logging buffer"
+ save_config_cmd: 'write'
+ save_config_confirm: False
+ save_config_response: 'OK'
+
+centec_os:
+ version: "show version"
+ basic: "show ip interface brief"
+ extended_output: "show version"
+ config:
+ - "ip access-list centec"
+ config_verification: "show running-config | include ip access-list centec"
+ 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"
+ extended_output: "system diagnostics show version-info"
+
+adtran_os:
+ version: "show version"
+ basic: "show system-management-evc"
+ extended_output: "show version"
+
+huawei_smartax:
+ version: "display version"
+ basic: "display system sys-info"
+ extended_output: "display version"
+ config:
+ - acl 2456
+ config_verification: "display current-configuration | include acl 2456"
+
+tplink_jetstream:
+ version: "show system-info"
+ basic: "show interface vlan 1"
+ extended_output: "show running-config all"
+ config:
+ - "no clipaging"
+ config_verification: "show running-config | include clipaging"
+
+tplink_jetstream_telnet:
+ version: "show system-info"
+ basic: "show interface vlan 1"
+ extended_output: "show running-config all"
+ config:
+ - "no clipaging"
+ config_verification: "show running-config | include clipaging"
+
+ubiquiti_edgerouter:
+ version: "show version"
+ basic: "show interfaces switch switch0"
+ extended_output: "show configuration all"
+ config:
+ - "set system coredump enabled true"
+ - "set system coredump enabled false"
+ support_commit: True
+ config_verification: "show system coredump enabled"
+
+zyxel_os:
+ version: "sys atsh"
+ basic: "cfg lan get"
+ extended_output: "cfg wlan get"
+ config:
+ - "cfg wlan edit --Band 2.4GHz --MainSSID 1 --SSID 'NetmikoTest'"
+ - "cfg wlan edit --Band 2.4GHz --MainSSID 1 --SSID 'magic2000'"
+ config_verification: "cfg intf_group get"
diff --git a/tests/etc/index b/tests/etc/index
new file mode 100644
index 000000000..36d409c5d
--- /dev/null
+++ b/tests/etc/index
@@ -0,0 +1,2 @@
+Template, Hostname, Platform, Command
+cisco_ios_show_version.template, .*, cisco_ios, sh[[ow]] ver[[sion]]
\ No newline at end of file
diff --git a/tests/etc/responses.yml.example b/tests/etc/responses.yml.example
index 12ffc6b82..d119af365 100644
--- a/tests/etc/responses.yml.example
+++ b/tests/etc/responses.yml.example
@@ -8,6 +8,7 @@ cisco_ios:
version_banner: "Cisco IOS Software"
multiple_line_output: "Configuration register is"
file_check_cmd: "logging buffered 8880"
+ save_config: 'OK'
juniper:
base_prompt: pyclass@pynet-jnpr-srx1
@@ -20,6 +21,16 @@ juniper:
cmd_response_final: 'archive size 120k files 3'
commit_comment: 'Unit test on commit with comment'
+juniper_screenos:
+ base_prompt: "ssg5-serial-"
+ router_prompt: "ssg5-serial->"
+ enable_prompt: "ssg5-serial->"
+ interface_ip: 100.65.1.1
+ multiple_line_output: 'Total Config size'
+ version_banner: 'Version: 6.3.0.1.0.0.0.0'
+ cmd_response_init: ""
+ cmd_response_final: 'set alias test'
+
paloalto_panos:
base_prompt: ntc@pa1
router_prompt: ntc@pa1>
@@ -78,6 +89,37 @@ ubiquiti_edge:
cmd_response_init: ""
cmd_response_final: "logging persistent 4"
+ubiquiti_unifiswitch:
+ base_prompt: "(UBNT) "
+ router_prompt: "(UBNT) >"
+ enable_prompt: "(UBNT) #"
+ interface_ip: 10.0.132.4
+ version_banner: "Software Version"
+ multiple_line_output: "Current Configuration:"
+ cmd_response_init: ""
+ cmd_response_final: "logging persistent 4"
+
+dellos10:
+ base_prompt: OS10
+ router_prompt : OS10#
+ enable_prompt: OS10#
+ interface_ip: 192.168.23.129
+ version_banner: "Dell EMC Networking OS10-Enterprise"
+ multiple_line_output: "Last configuration change"
+ cmd_response_init: "host-description test"
+ cmd_response_final: "host-description node"
+ scp_remote_space: 1000
+
+dell_sonic:
+ base_prompt: sonic
+ router_prompt : sonic#
+ enable_prompt: sonic#
+ interface_ip: 10.10.10.1
+ version_banner: "Software Version"
+ multiple_line_output: "interface Management 0"
+ cmd_response_init: ""
+ cmd_response_final: "interface Vlan100"
+
dell_powerconnect:
base_prompt: myswitch
router_prompt : myswitch#
@@ -104,6 +146,14 @@ alcatel_aos:
version_banner: "Alcatel-Lucent OS6250-24 6.7.1.108.R04 Service Release, January 04, 2017"
multiple_line_output: "FC - ForcedCopper PC - PreferredCopper C - Copper"
+netscaler:
+ base_prompt: ">"
+ router_prompt: ">"
+ enable_prompt: ">"
+ interface_ip: "192.168.10.10"
+ multiple_line_output: "Netscaler Loopback interface"
+ version_banner: "NetScaler"
+
calix_b6_ssh:
base_prompt: CALIX-B6-TEST
router_prompt: CALIX-B6-TEST>
@@ -112,4 +162,193 @@ calix_b6_ssh:
version_banner: "Kernel build id 8.0.30.0"
multiple_line_output: "rtcPwrUptimeTotal"
cmd_response_init: "Building configuration... Done"
- cmd_response_final: "access-list ethernet 999 permit ip"
\ No newline at end of file
+ cmd_response_final: "access-list ethernet 999 permit ip"
+
+ipinfusion_ocnos:
+ base_prompt: rtr1
+ router_prompt: rtr1>
+ enable_prompt: rtr1#
+ interface_ip: 10.12.39.34
+ version_banner: "Software Product: OcNOS"
+ multiple_line_output: "lo 127.0.0.1"
+ cmd_response_init: "ospfd 2 4"
+ cmd_response_final: "ospfd 2 5"
+ save_config: '[OK]'
+
+ipinfusion_ocnos_telnet:
+ base_prompt: rtr1
+ router_prompt: rtr1>
+ enable_prompt: rtr1#
+ interface_ip: 10.12.39.34
+ version_banner: "Software Product: OcNOS"
+ multiple_line_output: "lo 127.0.0.1"
+ cmd_response_init: "ospfd 2 4"
+ cmd_response_final: "ospfd 2 5"
+ save_config: '[OK]'
+
+
+oneaccess_oneos:
+ base_prompt: dops-4glbb-01
+ router_prompt: dops-4glbb-01>
+ enable_prompt: dops-4glbb-01#
+ interface_ip: 10.94.49.187
+ version_banner: "Software version"
+ multiple_line_output: "Software created on"
+ file_check_cmd: "logging buffered 20010"
+ save_config: '[OK]'
+
+
+oneaccess_oneos_telnet:
+ base_prompt: dops-4glbb-01
+ router_prompt: dops-4glbb-01>
+ enable_prompt: dops-4glbb-01#
+ interface_ip: 10.94.49.187
+ version_banner: "Software version"
+ multiple_line_output: "Software created on"
+ file_check_cmd: "logging buffered 20010"
+ save_config: '[OK]'
+
+mikrotik_routeros:
+ base_prompt: '[admin@KLWNBC12RB01] '
+ enable_prompt: '[admin@KLWNBC12RB01] >'
+ config_prompt: '[admin@KLWNBC12RB01] >'
+ version_banner: "version: "
+ multiple_line_output: "out=.1.3.6.1.2.1.2.2.1.20.8"
+ interface_ip: "0 D "
+ cmd_response_init: "Flags: X "
+ cmd_response_final: "0 bridge1"
+
+cloudgenix_ion:
+ base_prompt: 'US-0002-ION-01'
+ enable_prompt: 'US-0002-ION-01#'
+ config_prompt: 'US-0002-ION-01#'
+ version_banner: "CurrentVersion"
+ multiple_line_output: "eth3.207@eth3: mtu 1500 qdisc noqueue state UP mode DEFAULT gr\noup default qlen 1000\n link/ether ec:b9:07:00:91:09 brd ff:ff:ff:ff:ff"
+ interface_ip: "192.168.1.16/24"
+ cmd_response_init: "172.16.16.15/24"
+ cmd_response_final: "172.16.16.16/24"
+
+keymile:
+ base_prompt: /
+ router_prompt: />
+ enable_prompt: />
+ interface_ip: 1.2.3.4
+ version_banner: "---===### CLI Release R2A21, Build 2018-12-21 ###===---"
+ multiple_line_output: "Equipment State"
+
+keymile_nos:
+ base_prompt: KDKB1251
+ router_prompt: KDKB1251>
+ enable_prompt: KDKB1251#
+ interface_ip: 1.2.3.5
+ version_banner: "NOS version 2.09 #0001"
+ multiple_line_output: "Interface br328"
+
+dlink_ds:
+ base_prompt: DGS-3120-24TC:admin
+ router_prompt: DGS-3120-24TC:admin#
+ enable_prompt: DGS-3120-24TC:admin#
+ version_banner: "D-Link Corporation"
+ multiple_line_output: "End of configuration file"
+ interface_ip: 192.168.50.10
+
+dlink_ds_telnet:
+ base_prompt: DGS-3120-24TC:admin
+ router_prompt: DGS-3120-24TC:admin#
+ enable_prompt: DGS-3120-24TC:admin#
+ version_banner: "D-Link Corporation"
+ multiple_line_output: "End of configuration file"
+ interface_ip: 192.168.50.10
+
+ruijie_os:
+ base_prompt: Ruijie
+ router_prompt : Ruijie>
+ enable_prompt: Ruijie#
+ interface_ip: 172.30.31.101
+ version_banner: "Ruijie Networks"
+ multiple_line_output: ""
+ file_check_cmd: "logging buffered 8880"
+ save_config: 'OK'
+
+centec_os:
+ base_prompt: Centec
+ router_prompt : Centec>
+ enable_prompt: Centec#
+ interface_ip: 172.30.31.101
+ 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>"
+ enable_prompt: "console>"
+ interface_ip: 172.16.16.16
+ version_banner: "Serial Number"
+ multiple_line_output: ""
+
+adtran_os:
+ base_prompt: "adtrantest"
+ router_prompt: "adtrantest>"
+ enable_prompt: "adtrantest#"
+ interface_ip: 192.0.2.1
+ version_banner: "Serial number"
+
+huawei_smartax:
+ base_prompt: "ol01.test-lab.xyz"
+ router_prompt: "ol01.test-lab.xyz>"
+ enable_prompt: "ol01.test-lab.xyz#"
+ interface_ip: 192.0.2.1
+ version_banner: "VERSION :"
+ multiple_line_output: ""
+
+tplink_jetstream:
+ base_prompt: "T1500G-10PS"
+ router_prompt: "T1500G-10PS>"
+ enable_prompt: "T1500G-10PS#"
+ interface_ip: 192.168.0.1
+ version_banner: "Software Version"
+ multiple_line_output: "interface vlan 1"
+ cmd_response_final: "no clipaging"
+
+tplink_jetstream_telnet:
+ base_prompt: "T1500G-10PS"
+ router_prompt: "T1500G-10PS>"
+ enable_prompt: "T1500G-10PS#"
+ interface_ip: 192.168.0.1
+ version_banner: "Software Version"
+ multiple_line_output: "interface vlan 1"
+ cmd_response_final: "no clipaging"
+
+ubiquiti_edgerouter:
+ base_prompt: "ubnt@edgerouter"
+ router_prompt: "ubnt@edgerouter:~$"
+ enable_prompt: "ubnt@edgerouter:~$"
+ interface_ip: "192.168.1.1"
+ version_banner: "Ubiquiti Networks, Inc"
+ multiple_line_output: "switch switch0 {"
+ cmd_response_init: "enabled true"
+ cmd_response_final: "enabled false"
+
+zyxel:
+ base_prompt: "ZySH"
+ router_prompt: "ZySH>"
+ enable_prompt: "ZySH>"
+ interface_ip: "192.168.1.100"
+ version_banner: "Zyxel Communications Corp."
+ multiple_line_output: "Index Band SSID Enable Bandwidth Channel MaxDevices SecurityMode PskValue"
+ cmd_response_init: "NetmikoTest"
+ cmd_response_final: "magic2000"
+
+extreme_exos:
+ scp_remote_space: 1000
\ No newline at end of file
diff --git a/tests/etc/ssh_config b/tests/etc/ssh_config
new file mode 100644
index 000000000..4176e7d9b
--- /dev/null
+++ b/tests/etc/ssh_config
@@ -0,0 +1,10 @@
+host jumphost
+ IdentityFile ~/.ssh/test_rsa
+ user myuser
+ hostname host1.domain.com
+
+host *
+ User admin
+ HostName 10.10.10.70
+ Port 8022
+ ProxyCommand ssh jumphost nc %h %p
diff --git a/tests/etc/ssh_config_proxyjump b/tests/etc/ssh_config_proxyjump
new file mode 100644
index 000000000..694a8dd71
--- /dev/null
+++ b/tests/etc/ssh_config_proxyjump
@@ -0,0 +1,10 @@
+host jumphost
+ IdentitiesOnly yes
+ IdentityFile ~/.ssh/test_rsa
+ user myuser
+ hostname host1.domain.com
+
+host * !jumphost
+ User admin
+ Port 8022
+ ProxyJump jumphost
diff --git a/tests/etc/test_devices.yml.example b/tests/etc/test_devices.yml.example
index 5c7a04133..96bd730e0 100644
--- a/tests/etc/test_devices.yml.example
+++ b/tests/etc/test_devices.yml.example
@@ -38,6 +38,12 @@ juniper:
username: admin
password: juniper123
+juniper_screenos:
+ device_type: juniper_screenos
+ ip: 100.65.1.1
+ username: netscreen
+ password: netscreen
+
paloalto_panos:
device_type: paloalto_panos
ip: 10.10.10.15
@@ -89,6 +95,18 @@ dell_powerconnect:
username: admin
password: admin
+dellos10:
+ device_type: dellos10
+ ip: 192.168.23.129
+ username: admin
+ password: admin
+
+dell_sonic:
+ device_type: dell_sonic
+ ip: 192.168.23.130
+ username: admin
+ password: admin
+
pluribus:
device_type: pluribus_ssh
ip: 172.17.19.1
@@ -101,9 +119,147 @@ alcatel_aos:
username: admin
password: switch
+netscaler:
+ device_type: netscaler
+ ip: 192.168.10.10
+ username: admin
+ password: admin
+
calix_b6_ssh:
device_type: calix_b6_ssh
ip: 192.168.99.99
username: cli
password: occam
- secret: razor
\ No newline at end of file
+ secret: razor
+
+ipinfusion_ocnos:
+ device_type: ipinfusion_ocnos
+ ip: 10.12.39.34
+ username: ocnos
+ password: ocnos
+ secret: ocnos
+
+ipinfusion_ocnos_telnet:
+ device_type: ipinfusion_ocnos_telnet
+ ip: 10.12.39.34
+ username: ocnos
+ password: ocnos
+ secret: ocnos
+
+oneaccess_oneos:
+ device_type: oneaccess_oneos
+ ip: 10.94.49.187
+ username: m-wallraf
+ password: TEST
+ secret: TEST
+
+oneaccess_oneos_telnet:
+ device_type: oneaccess_oneos_telnet
+ ip: 10.94.49.187
+ username: m-wallraf
+ password: TEST
+ secret: TEST
+
+mikrotik_routeros:
+ device_type: mikrotik_routeros
+ ip: 192.168.88.1
+ username: admin
+ password: ""
+
+cloudgenix_ion:
+ device_type: cloudgenix_ion
+ ip: 1.1.1.1
+ username: TEST
+ password: TEST
+
+keymile:
+ device_type: keymile
+ ip: 1.2.3.4
+ username: TEST
+ password: TEST
+
+keymile_nos:
+ device_type: keymile_nos
+ ip: 1.2.3.5
+ username: TEST
+ password: TEST
+
+dlink_ds:
+ device_type: dlink_ds
+ ip: 192.168.50.10
+ username: admin
+ password: admin
+
+dlink_ds_telnet:
+ device_type: dlink_ds_telnet
+ ip: 192.168.50.10
+ username: admin
+ password: admin
+
+ruijie_os:
+ device_type: ruijie_os
+ ip: 1.1.1.1
+ username: ruijie
+ password: ruijie
+ secret: ruijie
+
+centec_os:
+ device_type: centec_os
+ ip: 1.1.1.1
+ username: centec
+ 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
+ username: admin
+ password: admin
+
+adtran_os:
+ device_type: adtran_os
+ ip: 192.0.2.1
+ username: adtran
+ password: adtran
+
+huawei_smartax:
+ device_type: huawei_smartax
+ ip: 192.0.2.1
+ username: TEST
+ password: TEST
+
+tplink_jetstream:
+ device_type: tplink_jetstream
+ ip: 192.168.0.1
+ username: admin
+ password: 'admin'
+
+tplink_jetstream_telnet:
+ device_type: tplink_jetstream_telnet
+ ip: 192.168.0.1
+ username: admin
+ password: 'admin'
+
+ubiquiti_edgerouter:
+ device_type: ubiquiti_edgerouter
+ ip: 192.168.1.1
+ username: ubnt
+ password: ubnt
+
+zyxel:
+ device_type: zyxel_os
+ ip: 192.168.1.1
+ username: admin
+ password: 'pass'
+
+extreme_exos:
+ device_type: extreme_exos
+ ip: 192.0.2.1
+ username: admin
+ password: 'admin'
\ No newline at end of file
diff --git a/tests/etc/textfsm.txt b/tests/etc/textfsm.txt
new file mode 100644
index 000000000..d20b5886e
--- /dev/null
+++ b/tests/etc/textfsm.txt
@@ -0,0 +1 @@
+Cisco IOS Software, Catalyst 4500 L3 Switch Software
\ No newline at end of file
diff --git a/tests/etc/yaml_test.yml b/tests/etc/yaml_test.yml
new file mode 100644
index 000000000..6a3e91558
--- /dev/null
+++ b/tests/etc/yaml_test.yml
@@ -0,0 +1,6 @@
+---
+hello: world
+answer: 42
+complex:
+ key: value
+ truth: false
diff --git a/tests/for_loop.sh b/tests/for_loop.sh
deleted file mode 100755
index 7134e8c60..000000000
--- a/tests/for_loop.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-for i in `seq 1 10`; do
-# ./test_arista.sh
- py.test -s -v test_netmiko_config.py --test_device arista_sw4
-done
diff --git a/tests/network_utilities.py b/tests/network_utilities.py
new file mode 100644
index 000000000..24f21bc87
--- /dev/null
+++ b/tests/network_utilities.py
@@ -0,0 +1,215 @@
+from ipaddress import ip_address
+
+
+def generate_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ip access-list extended",
+ base_addr="192.168.0.0",
+):
+ cmd = f"{base_cmd} {acl_name}"
+ acl = [cmd]
+ for i in range(1, entries + 1):
+ addr = ip_address(base_addr)
+ cmd = f"permit ip host {addr + i} any"
+ acl.append(cmd)
+ return acl
+
+
+def generate_hp_procurve_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ip access-list extended",
+ base_addr="192.168.0.0",
+):
+ """
+ Faked an ACL as did not see easy way to create ACL on my HPE device.
+
+ Just remove and add NTP server so 100 lines of cfg changes.
+ """
+
+ base_acl = [
+ "no sntp server 128.118.25.3",
+ "sntp server 128.118.25.3",
+ ]
+ acl = []
+ for _ in range(50):
+ acl += base_acl
+ return acl
+
+
+def generate_ios_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ip access-list extended",
+ base_addr="192.168.0.0",
+):
+ return generate_acl(
+ acl_name=acl_name, entries=entries, base_cmd=base_cmd, base_addr=base_addr
+ )
+
+
+def generate_arista_eos_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ip access-list",
+ base_addr="192.168.0.0",
+):
+ return generate_acl(
+ acl_name=acl_name, entries=entries, base_cmd=base_cmd, base_addr=base_addr
+ )
+
+
+generate_cisco_ios_acl = generate_ios_acl
+generate_cisco_xe_acl = generate_ios_acl
+
+
+def generate_nxos_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ip access-list",
+ base_addr="192.168.0.0",
+):
+ return generate_acl(
+ acl_name=acl_name, entries=entries, base_cmd=base_cmd, base_addr=base_addr
+ )
+
+
+generate_cisco_nxos_acl = generate_nxos_acl
+
+
+def generate_cisco_xr_acl(
+ acl_name="netmiko_test_large_acl",
+ entries=100,
+ base_cmd="ipv4 access-list",
+ base_addr="192.168.0.0",
+):
+
+ # Add base ACL command
+ cmd = f"{base_cmd} {acl_name}"
+ acl = [cmd]
+ for i in range(1, entries + 1):
+ addr = ip_address(base_addr)
+ cmd = f"permit ipv4 host {addr + i} any"
+ acl.append(cmd)
+ 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
+
+
+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)
+ ios_ref_acl = [
+ "ip access-list extended netmiko_test_large_acl",
+ "permit ip host 192.168.0.1 any",
+ "permit ip host 192.168.0.2 any",
+ "permit ip host 192.168.0.3 any",
+ "permit ip host 192.168.0.4 any",
+ "permit ip host 192.168.0.5 any",
+ "permit ip host 192.168.0.6 any",
+ "permit ip host 192.168.0.7 any",
+ "permit ip host 192.168.0.8 any",
+ "permit ip host 192.168.0.9 any",
+ "permit ip host 192.168.0.10 any",
+ ]
+
+ assert acl == ios_ref_acl
+
+ acl = generate_nxos_acl(entries=10)
+ nxos_ref_acl = [
+ "ip access-list netmiko_test_large_acl",
+ "permit ip host 192.168.0.1 any",
+ "permit ip host 192.168.0.2 any",
+ "permit ip host 192.168.0.3 any",
+ "permit ip host 192.168.0.4 any",
+ "permit ip host 192.168.0.5 any",
+ "permit ip host 192.168.0.6 any",
+ "permit ip host 192.168.0.7 any",
+ "permit ip host 192.168.0.8 any",
+ "permit ip host 192.168.0.9 any",
+ "permit ip host 192.168.0.10 any",
+ ]
+ assert acl == nxos_ref_acl
+
+ acl = generate_cisco_xr_acl(entries=10)
+ xr_ref_acl = [
+ "ipv4 access-list netmiko_test_large_acl",
+ "permit ipv4 host 192.168.0.1 any",
+ "permit ipv4 host 192.168.0.2 any",
+ "permit ipv4 host 192.168.0.3 any",
+ "permit ipv4 host 192.168.0.4 any",
+ "permit ipv4 host 192.168.0.5 any",
+ "permit ipv4 host 192.168.0.6 any",
+ "permit ipv4 host 192.168.0.7 any",
+ "permit ipv4 host 192.168.0.8 any",
+ "permit ipv4 host 192.168.0.9 any",
+ "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
+
+ 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/performance/gen_graph.py b/tests/performance/gen_graph.py
new file mode 100644
index 000000000..e7ac2a1d8
--- /dev/null
+++ b/tests/performance/gen_graph.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+import os
+import pygal
+import csv
+import yaml
+import jinja2
+from pprint import pprint
+from typing import Dict
+
+from pathlib import Path
+
+
+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.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
+
+
+def filter_versions(entries):
+ patches = dict()
+ for entry in entries:
+ version = entry["netmiko_version"]
+ dot_pos = version.rfind(".")
+ minor_version = version[:dot_pos]
+ dot_pos += 1
+ patch_version = version[dot_pos:]
+ current_patch = patches.get(minor_version, "0")
+ patches[minor_version] = max(patch_version, current_patch)
+
+ last_versions = [f"{minor}.{patch}" for minor, patch in patches.items()]
+ entries = filter(lambda x: x["netmiko_version"] in last_versions, entries)
+ return sorted(entries, key=lambda x: x["netmiko_version"])
+
+
+def generate_graph(device_name: str, params: Dict) -> None:
+ device = device_name
+ title = params["graph"]["title"]
+ device_dict = params["device"]
+ device_type = device_dict["device_type"]
+ outfile = f"netmiko_{device_type}.svg"
+ entries = read_csv(device)
+ entries = filter_versions(entries)
+
+ # 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)
+ dir_path = Path.cwd() / "graphs"
+ if not dir_path.exists():
+ dir_path.mkdir()
+ line_chart.render_to_file(str(dir_path / outfile))
+
+
+perf_report_template = """
+# Netmiko performance
+{%- for graph in graphs %}
+\n
+{%- endfor %}
+"""
+
+
+def generate_report():
+ template = jinja2.Template(perf_report_template)
+ graphs_path = Path.cwd() / "graphs"
+ graph_files = ["graphs/" + item.name for item in graphs_path.iterdir()]
+ report_file = Path.cwd() / "performance_report.md"
+ with report_file.open("w") as out_file:
+ out_file.writelines(template.render({"graphs": graph_files}))
+
+
+if __name__ == "__main__":
+ f_name = os.environ.get("TEST_DEVICES", "test_devices.yml")
+ with open(f_name) as f:
+ devices = yaml.load(f)
+ for device_name, device in devices.items():
+ if "graph" in device:
+ generate_graph(device_name, device)
+ generate_report()
diff --git a/tests/performance/graphs/netmiko_arista_eos.svg b/tests/performance/graphs/netmiko_arista_eos.svg
new file mode 100644
index 000000000..4ac71b343
--- /dev/null
+++ b/tests/performance/graphs/netmiko_arista_eos.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_cisco_asa.svg b/tests/performance/graphs/netmiko_cisco_asa.svg
new file mode 100644
index 000000000..085d84e58
--- /dev/null
+++ b/tests/performance/graphs/netmiko_cisco_asa.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_cisco_ios.svg b/tests/performance/graphs/netmiko_cisco_ios.svg
new file mode 100644
index 000000000..433fbce9b
--- /dev/null
+++ b/tests/performance/graphs/netmiko_cisco_ios.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_cisco_nxos.svg b/tests/performance/graphs/netmiko_cisco_nxos.svg
new file mode 100644
index 000000000..c9a43e8cb
--- /dev/null
+++ b/tests/performance/graphs/netmiko_cisco_nxos.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_cisco_xe.svg b/tests/performance/graphs/netmiko_cisco_xe.svg
new file mode 100644
index 000000000..64d0f1209
--- /dev/null
+++ b/tests/performance/graphs/netmiko_cisco_xe.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_cisco_xr.svg b/tests/performance/graphs/netmiko_cisco_xr.svg
new file mode 100644
index 000000000..c5692b297
--- /dev/null
+++ b/tests/performance/graphs/netmiko_cisco_xr.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_hp_procurve.svg b/tests/performance/graphs/netmiko_hp_procurve.svg
new file mode 100644
index 000000000..1eec9431b
--- /dev/null
+++ b/tests/performance/graphs/netmiko_hp_procurve.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/graphs/netmiko_juniper_junos.svg b/tests/performance/graphs/netmiko_juniper_junos.svg
new file mode 100644
index 000000000..438892120
--- /dev/null
+++ b/tests/performance/graphs/netmiko_juniper_junos.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/tests/performance/netmiko_performance.csv b/tests/performance/netmiko_performance.csv
new file mode 100644
index 000000000..71f1b9f31
--- /dev/null
+++ b/tests/performance/netmiko_performance.csv
@@ -0,0 +1,63 @@
+date,netmiko_version,device_name,connect,send_command_simple,send_config_simple,send_config_large_acl
+2021-9-5 1:55:18,2.4.2,cisco1,0:00:05.015699,0:00:05.437302,0:00:07.712221,0:00:12.729495
+2021-9-5 1:55:59,2.4.2,cisco3,0:00:04.824338,0:00:05.343782,0:00:07.538030,0:00:15.060866
+2021-9-5 1:56:43,2.4.2,cisco5,0:00:05.407796,0:00:05.773626,0:00:08.139664,0:00:16.210261
+2021-9-5 1:57:26,2.4.2,nxos1,0:00:04.987734,0:00:05.362760,0:00:07.674167,0:00:15.172741
+2021-9-5 1:58:23,2.4.2,cisco_xr_azure,0:00:05.733791,0:00:06.082400,0:00:13.662819,0:00:18.556989
+2021-9-5 1:59:13,2.4.2,arista1,0:00:05.600851,0:00:06.615937,0:00:08.651368,0:00:17.739594
+2021-9-5 2:0:43,2.4.2,juniper_vmx,0:00:06.955827,0:00:07.795193,0:00:20.183726,0:00:35.183576
+2021-9-5 2:3:4,2.4.2,cisco_asa,0:00:20.615055,0:00:21.104976,0:00:31.040221,0:00:36.460483
+2021-9-5 2:6:52,3.0.0,cisco1,0:00:05.692225,0:00:06.039594,0:00:05.965445,0:00:16.356528
+2021-9-5 2:7:32,3.0.0,cisco3,0:00:05.340213,0:00:05.961108,0:00:05.810182,0:00:16.613027
+2021-9-5 2:8:21,3.0.0,cisco5,0:00:06.184334,0:00:06.507650,0:00:06.594281,0:00:23.760243
+2021-9-5 2:9:3,3.0.0,nxos1,0:00:05.704003,0:00:06.289166,0:00:05.935209,0:00:17.162782
+2021-9-5 2:9:59,3.0.0,cisco_xr_azure,0:00:06.266681,0:00:06.900057,0:00:11.732624,0:00:19.812287
+2021-9-5 2:11:2,3.0.0,arista1,0:00:06.215650,0:00:06.971088,0:00:07.130959,0:00:34.856952
+2021-9-5 2:12:34,3.0.0,juniper_vmx,0:00:08.245966,0:00:08.638104,0:00:18.754187,0:00:37.204469
+2021-9-5 2:14:45,3.0.0,cisco_asa,0:00:18.416279,0:00:19.348867,0:00:27.323944,0:00:38.590701
+2021-9-5 2:39:13,3.1.0,cisco1,0:00:07.788300,0:00:08.142923,0:00:08.065553,0:00:18.461486
+2021-9-5 2:40:3,3.1.0,cisco3,0:00:07.536840,0:00:07.961087,0:00:07.810232,0:00:18.580455
+2021-9-5 2:41:0,3.1.0,cisco5,0:00:08.109600,0:00:08.267561,0:00:08.221555,0:00:23.761802
+2021-9-5 2:41:54,3.1.0,nxos1,0:00:07.652550,0:00:08.914154,0:00:07.975704,0:00:21.243036
+2021-9-5 2:42:51,3.1.0,cisco_xr_azure,0:00:06.264205,0:00:06.999404,0:00:12.024759,0:00:19.590199
+2021-9-5 2:43:52,3.1.0,arista1,0:00:06.258040,0:00:06.704600,0:00:07.223195,0:00:34.630821
+2021-9-5 2:45:24,3.1.0,juniper_vmx,0:00:07.763991,0:00:08.640627,0:00:18.747711,0:00:37.257378
+2021-9-5 2:47:33,3.1.0,cisco_asa,0:00:18.258663,0:00:18.908106,0:00:27.182697,0:00:37.982340
+2021-9-5 7:4:42,3.3.3,cisco1,0:00:03.047461,0:00:03.134423,0:00:03.140944,0:00:05.528239
+2021-9-5 7:5:3,3.3.3,cisco3,0:00:03.070582,0:00:03.149141,0:00:03.024375,0:00:08.902653
+2021-9-5 7:5:33,3.3.3,cisco5,0:00:03.792198,0:00:03.464545,0:00:03.491411,0:00:14.720161
+2021-9-5 7:6:28,3.3.3,nxos1,0:00:07.945623,0:00:07.960268,0:00:08.498077,0:00:22.775075
+2021-9-5 7:7:20,3.3.3,cisco_xr_azure,0:00:08.140628,0:00:08.500045,0:00:09.143244,0:00:16.494184
+2021-9-5 7:8:3,3.3.3,arista1,0:00:01.904317,0:00:02.497181,0:00:03.357669,0:00:32.008313
+2021-9-5 7:9:10,3.3.3,juniper_vmx,0:00:03.517362,0:00:04.262974,0:00:14.697604,0:00:29.589270
+2021-9-5 7:9:40,3.3.3,cisco_asa,0:00:04.741192,0:00:04.579358,0:00:05.075321,0:00:10.911831
+2021-9-5 7:12:46,3.4.0,cisco3,0:00:03.067946,0:00:02.977177,0:00:03.222384,0:00:10.138406
+2021-9-5 7:13:15,3.4.0,cisco5,0:00:03.739743,0:00:03.374246,0:00:03.651205,0:00:13.728987
+2021-9-5 7:14:9,3.4.0,nxos1,0:00:07.719243,0:00:08.216120,0:00:08.309425,0:00:22.034908
+2021-9-5 7:15:2,3.4.0,cisco_xr_azure,0:00:08.073150,0:00:08.433702,0:00:09.295759,0:00:17.251342
+2021-9-5 7:15:43,3.4.0,arista1,0:00:02.280802,0:00:02.812860,0:00:02.930811,0:00:30.112190
+2021-9-5 7:16:51,3.4.0,juniper_vmx,0:00:03.991287,0:00:04.162200,0:00:16.791620,0:00:27.660851
+2021-9-5 7:17:20,3.4.0,cisco_asa,0:00:04.767506,0:00:04.783185,0:00:05.082772,0:00:10.640835
+2021-9-5 2:52:20,3.2.0,cisco1,0:00:07.715810,0:00:08.145355,0:00:08.063230,0:00:18.446518
+2021-9-5 2:53:10,3.2.0,cisco3,0:00:07.527892,0:00:07.963046,0:00:07.807690,0:00:18.531863
+2021-9-5 2:54:7,3.2.0,cisco5,0:00:08.203857,0:00:08.116193,0:00:08.307243,0:00:23.778882
+2021-9-5 2:55:1,3.2.0,nxos1,0:00:07.812037,0:00:08.369030,0:00:08.207090,0:00:21.624220
+2021-9-5 2:55:59,3.2.0,cisco_xr_azure,0:00:06.273295,0:00:06.884430,0:00:11.881486,0:00:20.203558
+2021-9-5 2:57:50,3.2.0,arista1,0:00:08.236209,0:00:08.897231,0:00:17.371332,0:00:56.674599
+2021-9-5 2:59:22,3.2.0,juniper_vmx,0:00:07.762834,0:00:08.832251,0:00:18.852219,0:00:37.785493
+2021-9-5 3:1:32,3.2.0,cisco_asa,0:00:18.131249,0:00:19.274312,0:00:27.334803,0:00:37.721248
+2021-9-5 12:4:4,4.0.0a4,cisco1,0:00:03.069351,0:00:03.094754,0:00:03.118014,0:00:06.244000
+2021-9-5 12:4:27,4.0.0a4,cisco3,0:00:02.897018,0:00:03.136093,0:00:03.218576,0:00:11.184475
+2021-9-5 12:4:57,4.0.0a4,cisco5,0:00:03.611916,0:00:03.428950,0:00:03.722674,0:00:15.478373
+2021-9-5 12:5:40,4.0.0a4,nxos1,0:00:05.139839,0:00:05.173450,0:00:05.690468,0:00:21.206284
+2021-9-5 12:6:1,4.0.0a4,cisco_xr_azure,0:00:01.825557,0:00:02.395446,0:00:02.922008,0:00:11.205408
+2021-9-5 12:6:30,4.0.0a4,arista1,0:00:01.845722,0:00:02.855799,0:00:02.429823,0:00:18.554945
+2021-9-5 12:7:51,4.0.0a4,juniper_vmx,0:00:05.827800,0:00:06.318494,0:00:19.309357,0:00:30.160754
+2021-9-5 12:8:21,4.0.0a4,cisco_asa,0:00:04.641249,0:00:04.920887,0:00:05.718624,0:00:10.172494
+2021-10-2 14:27:36,2.4.2,hp_procurve,0:00:11.258269,0:00:21.831155,0:00:32.216741,0:00:42.488945
+2021-10-2 14:29:32,3.0.0,hp_procurve,0:00:17.901763,0:00:22.221532,0:00:30.534230,0:00:42.045111
+2021-10-2 14:31:31,3.1.0,hp_procurve,0:00:18.419321,0:00:22.937060,0:00:31.002139,0:00:42.630991
+2021-10-2 14:33:29,3.2.0,hp_procurve,0:00:18.353988,0:00:22.718488,0:00:30.893432,0:00:42.584148
+2021-10-2 14:35:27,3.3.3,hp_procurve,0:00:18.020695,0:00:22.391657,0:00:30.752905,0:00:42.227986
+2021-10-2 14:37:24,3.4.0,hp_procurve,0:00:18.010017,0:00:22.410676,0:00:30.529921,0:00:42.211889
+2021-10-4 14:34:42,4.0.0a4,hp_procurve,0:00:02.184035,0:00:02.524702,0:00:02.561778,0:00:10.813657
diff --git a/tests/performance/performance_report.md b/tests/performance/performance_report.md
new file mode 100644
index 000000000..e4fff7b9c
--- /dev/null
+++ b/tests/performance/performance_report.md
@@ -0,0 +1,10 @@
+
+# Netmiko performance
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/performance/setup.sh b/tests/performance/setup.sh
new file mode 100644
index 000000000..e2b903f48
--- /dev/null
+++ b/tests/performance/setup.sh
@@ -0,0 +1 @@
+export PYTHONPATH=/home/kbyers/netmiko/tests
diff --git a/tests/performance/test_devices.yml b/tests/performance/test_devices.yml
new file mode 100644
index 000000000..a2b08ff9e
--- /dev/null
+++ b/tests/performance/test_devices.yml
@@ -0,0 +1,76 @@
+---
+cisco1:
+ device:
+ device_type: cisco_ios
+ host: cisco1.lasthop.io
+ username: pyclass
+ graph:
+ title: "Netmiko: Cisco IOS Performance (Cisco 881)"
+
+cisco3:
+ device:
+ device_type: cisco_xe
+ host: cisco3.lasthop.io
+ username: pyclass
+ graph:
+ title: "Netmiko: Cisco IOS-XE Performance (Cisco C1111-4P)"
+
+cisco5:
+ device:
+ device_type: cisco_xe
+ host: cisco5.lasthop.io
+ username: pyclass
+
+nxos1:
+ device:
+ device_type: cisco_nxos
+ host: nxos1.lasthop.io
+ username: pyclass
+ graph:
+ title: "Netmiko: Cisco NX-OS Performance (nx9k virtual)"
+
+cisco_xr_azure:
+ device:
+ device_type: cisco_xr
+ host: iosxr3.lasthop.io
+ username: pyclass
+ secret: ''
+ graph:
+ title: "Netmiko: Cisco IOS-XR Performance (cisco IOS-XRv 9000)"
+
+arista1:
+ device:
+ device_type: arista_eos
+ host: arista1.lasthop.io
+ username: pyclass
+ graph:
+ title: "Netmiko: Arista EOS Performance (vEOS)"
+
+juniper_vmx:
+ device:
+ device_type: juniper_junos
+ host: vmx1.lasthop.io
+ username: pyclass
+ session_log: vmx1.out
+ graph:
+ title: "Netmiko: Juniper Junos Performance"
+
+cisco_asa:
+ device:
+ device_type: cisco_asa
+ ip: 184.105.247.88
+ username: pyclass
+ allow_auto_change: True
+ session_log: asa1.out
+ graph:
+ title: "Netmiko: Cisco ASA Performance"
+
+hp_procurve:
+ device:
+ device_type: hp_procurve
+ ip: 184.105.247.68
+ username: admin
+ secret: ""
+ session_log: hpe.out
+ graph:
+ title: "Netmiko: HPE ProCurve Performance"
diff --git a/tests/performance/test_netmiko.py b/tests/performance/test_netmiko.py
new file mode 100644
index 000000000..155f3b32e
--- /dev/null
+++ b/tests/performance/test_netmiko.py
@@ -0,0 +1,217 @@
+import os
+from os import path
+import yaml
+import time
+import functools
+from datetime import datetime
+import csv
+
+from netmiko import ConnectHandler, __version__
+from test_utils import parse_yaml
+
+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__))
+
+
+def commands(platform):
+ """Parse the commands.yml file to get a commands dictionary."""
+ test_platform = platform
+ commands_yml = parse_yaml(PWD + "/../etc/commands.yml")
+ return commands_yml[test_platform]
+
+
+def generate_csv_timestamp():
+ """yyyy-MM-dd HH:mm:ss"""
+ now = datetime.now()
+ t_stamp = f"{now.year}-{now.month}-{now.day} {now.hour}:{now.minute}:{now.second}"
+ return t_stamp
+
+
+def write_csv(device_name, netmiko_results):
+ results_file = "netmiko_performance.csv"
+ file_exists = os.path.isfile(results_file)
+ with open(results_file, "a") as csv_file:
+ field_names = ["date", "netmiko_version", "device_name"] + list(
+ netmiko_results.keys()
+ )
+ t_stamp = generate_csv_timestamp()
+ csv_write = csv.DictWriter(csv_file, fieldnames=field_names)
+
+ # Write the header only once
+ if not file_exists:
+ csv_write.writeheader()
+
+ entry = {
+ "date": t_stamp,
+ "netmiko_version": __version__,
+ "device_name": device_name,
+ }
+
+ for func_name, exec_time in netmiko_results.items():
+ entry[func_name] = exec_time
+ csv_write.writerow(entry)
+
+
+def f_exec_time(func):
+ @functools.wraps(func)
+ def wrapper_decorator(*args, **kwargs):
+ start_time = datetime.now()
+ result = func(*args, **kwargs)
+ end_time = datetime.now()
+ time_delta = end_time - start_time
+ print(f"{str(func)}: Elapsed time: {time_delta}")
+ return (time_delta, result)
+
+ return wrapper_decorator
+
+
+def read_devices():
+ f_name = os.environ.get("TEST_DEVICES", "test_devices.yml")
+ with open(f_name) as f:
+ return yaml.load(f)
+
+
+@f_exec_time
+def connect(device):
+ with ConnectHandler(**device) as conn:
+ prompt = conn.find_prompt()
+ PRINT_DEBUG and print(prompt)
+
+
+@f_exec_time
+def send_command_simple(device):
+ with ConnectHandler(**device) as conn:
+ platform = device["device_type"]
+ cmd = commands(platform)["basic"]
+ output = conn.send_command(cmd)
+ PRINT_DEBUG and print(output)
+
+
+@f_exec_time
+def send_config_simple(device):
+ with ConnectHandler(**device) as conn:
+ platform = device["device_type"]
+ cmd = commands(platform)["config"][0]
+ output = conn.send_config_set(cmd)
+ PRINT_DEBUG and print(output)
+
+
+@f_exec_time
+def send_config_large_acl(device):
+
+ # Results will be marginally distorted by generating the ACL here.
+ device_type = device["device_type"]
+ func_name = f"generate_{device_type}_acl"
+ func = getattr(network_utilities, func_name)
+
+ with ConnectHandler(**device) as conn:
+ cfg = func(entries=100)
+ output = conn.send_config_set(cfg)
+ PRINT_DEBUG and print(output)
+
+
+@f_exec_time
+def cleanup(device):
+
+ # Results will be marginally distorted by generating the ACL here.
+ platform = device["device_type"]
+ if "juniper_junos" in platform:
+ remove_acl_cmd = "rollback 0"
+ elif "hp_procurve" in platform:
+ remove_acl_cmd = None
+ 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}"
+ cleanup_generic(device, remove_acl_cmd)
+
+
+def cleanup_generic(device, command):
+ if command is None:
+ return
+ with ConnectHandler(**device) as conn:
+ output = conn.send_config_set(command)
+ PRINT_DEBUG and print(output)
+
+
+def remove_old_data(device_name):
+ results_file = "netmiko_performance.csv"
+ entries = []
+ with open(results_file) as f:
+ read_csv = csv.DictReader(f)
+ for entry in read_csv:
+ entry = dict(entry)
+ version, device = entry["netmiko_version"], entry["device_name"]
+ if (
+ version != __version__ and device == device_name
+ ) or device_name != device:
+ entries.append(entry)
+
+ with open(results_file, "w", newline="") as csv_file:
+ field_names = list(entries[0].keys())
+ csv_write = csv.DictWriter(csv_file, fieldnames=field_names)
+ csv_write.writeheader()
+ csv_write.writerows(entries)
+
+
+def main():
+ # PASSWORD = os.environ["HPE_PASSWORD"]
+ PASSWORD = os.environ["NORNIR_PASSWORD"]
+
+ devices = read_devices()
+ print("\n\n")
+ for dev_name, params in devices.items():
+ remove_old_data(dev_name)
+ dev_dict = params["device"]
+ # if dev_name != "cisco_xr_azure":
+ # 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 = [
+ "connect",
+ "send_command_simple",
+ "send_config_simple",
+ "send_config_large_acl",
+ "cleanup",
+ ]
+ results = {}
+ platform = dev_dict["device_type"]
+ for op in operations:
+ func = globals()[op]
+ time_delta, result = func(dev_dict)
+ if op != "cleanup":
+ results[op] = time_delta
+ # Some platforms have an issue where the last test affects the
+ # next test?
+ if "procurve" in platform:
+ time.sleep(30)
+ print("-" * 80)
+ print()
+
+ write_csv(dev_name, results)
+
+ print("\n\n")
+
+
+def test_performance():
+ main()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/performance/test_new_platform.sh b/tests/performance/test_new_platform.sh
new file mode 100755
index 000000000..fdeecbbd9
--- /dev/null
+++ b/tests/performance/test_new_platform.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+export PYTHONPATH=/home/kbyers/netmiko/tests
+export TEST_DEVICES=new_devices.yml
+
+pip show netmiko
+if [ $? -eq 0 ]; then
+ echo
+ echo "Verifying that netmiko is not installed ... [FAIL]"
+ echo "Uninstall netmiko package before running this script."
+ exit 1
+else
+ echo
+ echo "Verifying that netmiko is not installed ... [OK]"
+fi
+
+vers="2.4.2 3.0.0 3.1.0 3.2.0 3.3.3 3.4.0"
+# vers="4.0.0a4"
+
+for v in $vers
+do
+ echo "Testing version $v"
+ pip install netmiko==$v
+ pip show netmiko
+ py.test -s test_netmiko.py
+ result=$?
+ pip uninstall netmiko -y
+ if [ $result -eq 0 ]; then
+ echo
+ echo "Running performance tests ... [OK]"
+ echo
+ else
+ echo
+ echo "Running performance tests ... [FAIL]"
+ echo "Ensure that your current directory is {NETMIKO_REPO}/tests/performance"
+ exit 1
+ fi
+done
+
+python gen_graph.py
+if [ $? -eq 0 ]; then
+ echo
+ echo "Generating graphs ... [OK]"
+ echo
+else
+ echo
+ echo "Generating graphs ... [FAIL]"
+ echo "Ensure that your current directory is {NETMIKO_REPO}/tests/performance"
+ exit 1
+fi
diff --git a/tests/performance/test_performance.sh b/tests/performance/test_performance.sh
new file mode 100755
index 000000000..70c035c6f
--- /dev/null
+++ b/tests/performance/test_performance.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+export PYTHONPATH=/home/kbyers/netmiko/tests
+
+pip show pyaml pygal jinja2
+if [ $? -eq 0 ]; then
+ echo
+ echo "Checking dependencies ... [OK]"
+ echo
+else
+ echo
+ echo "Checking dependencies ... [FAIL]"
+ exit 1
+fi
+
+py.test -s test_netmiko.py
+if [ $? -eq 0 ]; then
+ echo
+ echo "Running performance tests ... [OK]"
+ echo
+else
+ echo
+ echo "Running performance tests ... [FAIL]"
+ echo "Ensure that your current directory is {NETMIKO_REPO}/tests/performance"
+ exit 1
+fi
+
+python gen_graph.py
+if [ $? -eq 0 ]; then
+ echo
+ echo "Generating graphs ... [OK]"
+ echo
+else
+ echo
+ echo "Generating graphs ... [FAIL]"
+ echo "Ensure that your current directory is {NETMIKO_REPO}/tests/performance"
+ exit 1
+fi
\ No newline at end of file
diff --git a/tests/remove_delay.sh b/tests/remove_delay.sh
new file mode 100755
index 000000000..4619b5d7f
--- /dev/null
+++ b/tests/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/run_live_tests.sh b/tests/run_live_tests.sh
new file mode 100755
index 000000000..a83b5ad7c
--- /dev/null
+++ b/tests/run_live_tests.sh
@@ -0,0 +1,27 @@
+cd test_cisco_ios/
+./test_ios.sh > ../test_out/test_cisco_ios.out 2> ../test_out/test_cisco_ios.stderr &
+
+cd ..
+cd test_cisco_nxos/
+./test_cisco_nxos.sh > ../test_out/test_cisco_nxos.out 2> ../test_out/test_cisco_nxos.stderr &
+
+cd ..
+cd test_cisco_xe
+./test_cisco_xe.sh > ../test_out/test_cisco_xe.out 2> ../test_out/test_cisco_xe.stderr &
+
+cd ..
+cd test_cisco_xr
+./test_iosxr.sh > ../test_out/test_cisco_xr_xrv.out 2> ../test_out/test_cisco_xr_xrv.stderr &
+./test_iosxr_azure.sh > ../test_out/test_cisco_xr_azure.out 2> ../test_out/test_cisco_xr_azure.stderr &
+
+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 &
+
+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/show_run_interfaces.ttp b/tests/show_run_interfaces.ttp
new file mode 100644
index 000000000..8e3722e52
--- /dev/null
+++ b/tests/show_run_interfaces.ttp
@@ -0,0 +1,2 @@
+interface {{ intf_name }}
+ description {{ description | ORPHRASE}}
\ No newline at end of file
diff --git a/tests/test_arista.sh b/tests/test_arista.sh
deleted file mode 100755
index 1557bc1b1..000000000
--- a/tests/test_arista.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Arista" \
-&& py.test -v test_netmiko_show.py --test_device arista_sw4 \
-&& py.test -v test_netmiko_config.py --test_device arista_sw4 \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_arista_eos/add_delay_cisco_xe.sh b/tests/test_arista_eos/add_delay_cisco_xe.sh
new file mode 100755
index 000000000..9091873db
--- /dev/null
+++ b/tests/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/test_arista_eos/test9.txt b/tests/test_arista_eos/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_arista_eos/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_arista_eos/test_arista_eos.sh b/tests/test_arista_eos/test_arista_eos.sh
new file mode 100755
index 000000000..35d7f43c8
--- /dev/null
+++ b/tests/test_arista_eos/test_arista_eos.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+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 \
+&& py.test -s -x -v test_netmiko_autodetect.py --test_device arista_sw \
+|| RETURN_CODE=1
+
+exit $RETURN_CODE
diff --git a/tests/test_arista_eos/testx.txt b/tests/test_arista_eos/testx.txt
new file mode 100755
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_arista_eos/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_asa.sh b/tests/test_asa.sh
deleted file mode 100755
index 0b7b90a0c..000000000
--- a/tests/test_asa.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/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 cisco_asa_login \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa_login \
-&& py.test -v test_netmiko_show.py --test_device cisco_asa \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_autodetect.sh b/tests/test_autodetect.sh
deleted file mode 100755
index 35db457b0..000000000
--- a/tests/test_autodetect.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Autodetect tests" \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco881 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device arista_sw4 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device juniper_srx \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_asa \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_xrv \
-\
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
-
diff --git a/tests/test_cisco.sh b/tests/test_cisco.sh
deleted file mode 100755
index cb4e5f341..000000000
--- a/tests/test_cisco.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Cisco IOS SSH" \
-&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_config \
-&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_config \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
-
diff --git a/tests/test_cisco_asa/add_delay_cisco_asa.sh b/tests/test_cisco_asa/add_delay_cisco_asa.sh
new file mode 100755
index 000000000..a9f4bb70a
--- /dev/null
+++ b/tests/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/test_cisco_asa/test9.txt b/tests/test_cisco_asa/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_asa/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_asa/test_cisco_asa.sh b/tests/test_cisco_asa/test_cisco_asa.sh
new file mode 100755
index 000000000..384075196
--- /dev/null
+++ b/tests/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/test_cisco_asa/testx.txt b/tests/test_cisco_asa/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_asa/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_ios/add_delay_cisco881.sh b/tests/test_cisco_ios/add_delay_cisco881.sh
new file mode 100755
index 000000000..46decf6f9
--- /dev/null
+++ b/tests/test_cisco_ios/add_delay_cisco881.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.70/32 flowid 1:3
+
diff --git a/tests/test_cisco_ios/test9.txt b/tests/test_cisco_ios/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_ios/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_ios/test_ios.sh b/tests/test_cisco_ios/test_ios.sh
new file mode 100755
index 000000000..ebcfa9267
--- /dev/null
+++ b/tests/test_cisco_ios/test_ios.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+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 \
+&& py.test -s -x -v test_netmiko_tcl.py --test_device cisco1 \
+&& py.test -s -x -v test_netmiko_scp.py --test_device cisco1 \
+&& py.test -s -x -v test_netmiko_autodetect.py --test_device cisco1 \
+|| RETURN_CODE=1
+
+exit $RETURN_CODE
+
+# Note, it is possible the test_netmiko_cmd_verify tests fail as you are
+# attempting to do things with cmd_verify/global_cmd_verify set to False.
diff --git a/tests/test_cisco_ios/testx.txt b/tests/test_cisco_ios/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_ios/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_ios_serial.py b/tests/test_cisco_ios_serial.py
deleted file mode 100644
index f5c8930d6..000000000
--- a/tests/test_cisco_ios_serial.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-'''
-This will run an command via serial on an cisco ios switch and so
-serial cable must be attached to the device
-'''
-
-from __future__ import print_function
-from netmiko import ConnectHandler
-import serial
-
-def main():
- '''
- This will run an command via serial on an cisco ios switch and so
- serial cable must be attached to the device
- '''
- serialhandle = {
- 'device_type':'cisco_ios_serial',
- 'port': 'USB Serial', # can be COM or any line you can get from
- # serial.tools.list_ports.comports()
- 'username':'',
- 'password':'',
- 'secret':'',
- 'serial_settings':{ # this are the default values
- 'baudrate': 9600,
- 'bytesize': serial.EIGHTBITS,
- 'parity': serial.PARITY_NONE,
- 'stopbits': serial.STOPBITS_ONE
- }
- }
- net_connect = ConnectHandler(**serialhandle)
- net_connect.enable()
- output = net_connect.send_command('show run')
- net_connect.disconnect()
-
- print(output)
-
-if __name__ == "__main__":
- main()
diff --git a/tests/test_cisco_nxos/add_delay_cisco_nxos.sh b/tests/test_cisco_nxos/add_delay_cisco_nxos.sh
new file mode 100755
index 000000000..83d4d891a
--- /dev/null
+++ b/tests/test_cisco_nxos/add_delay_cisco_nxos.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 52.151.9.205/32 flowid 1:3
+
diff --git a/tests/test_cisco_nxos/test9.txt b/tests/test_cisco_nxos/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_nxos/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_nxos/test_cisco_nxos.sh b/tests/test_cisco_nxos/test_cisco_nxos.sh
new file mode 100755
index 000000000..27a4af710
--- /dev/null
+++ b/tests/test_cisco_nxos/test_cisco_nxos.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+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 \
+|| RETURN_CODE=1
+
+exit $RETURN_CODE
diff --git a/tests/test_cisco_nxos/testx.txt b/tests/test_cisco_nxos/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_nxos/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_w_key.py b/tests/test_cisco_w_key.py
deleted file mode 100755
index 5c28995ba..000000000
--- a/tests/test_cisco_w_key.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-from netmiko import ConnectHandler
-from os import path
-
-def main():
-
- try:
- hostname = raw_input("Enter remote host to test: ")
- except NameError:
- hostname = input("Enter remote host to test: ")
-
- home_dir = (path.expanduser('~'))
- key_file = "{}/.ssh/cisco_rsa".format(home_dir)
-
- cisco_test = {
- 'ip': hostname,
- 'username': 'testuser2',
- 'device_type': 'cisco_ios',
- 'use_keys': True,
- 'key_file': key_file,
- 'verbose': False}
-
- net_connect = ConnectHandler(**cisco_test)
- print()
- print("Checking prompt: ")
- print(net_connect.find_prompt())
- print()
- print("Testing show ip int brief: ")
- output = net_connect.send_command("show ip int brief")
- print(output)
- print()
-
-if __name__ == "__main__":
- main()
diff --git a/tests/test_cisco_xe/add_delay_cisco_xe.sh b/tests/test_cisco_xe/add_delay_cisco_xe.sh
new file mode 100755
index 000000000..5eef74d75
--- /dev/null
+++ b/tests/test_cisco_xe/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.89/32 flowid 1:3
+
diff --git a/tests/test_cisco_xe/test2_src.txt b/tests/test_cisco_xe/test2_src.txt
new file mode 100644
index 000000000..d2ddd3cb8
--- /dev/null
+++ b/tests/test_cisco_xe/test2_src.txt
@@ -0,0 +1,2 @@
+no logging console
+logging buffered 10000
diff --git a/tests/test_cisco_xe/test9.txt b/tests/test_cisco_xe/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_xe/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_xe/test_cisco_xe.sh b/tests/test_cisco_xe/test_cisco_xe.sh
new file mode 100755
index 000000000..2d117fe29
--- /dev/null
+++ b/tests/test_cisco_xe/test_cisco_xe.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+echo "Starting tests...good luck:" \
+&& cd .. \
+&& echo "Cisco IOS-XE" \
+&& 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/test_cisco_xe/testx.txt b/tests/test_cisco_xe/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_xe/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_xr/add_delay_iosxr_azure.sh b/tests/test_cisco_xr/add_delay_iosxr_azure.sh
new file mode 100755
index 000000000..e8441f880
--- /dev/null
+++ b/tests/test_cisco_xr/add_delay_iosxr_azure.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+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 40.121.206.54/32 flowid 1:3
+
diff --git a/tests/test_cisco_xr/test9.txt b/tests/test_cisco_xr/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_xr/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_cisco_xr/test_iosxr.sh b/tests/test_cisco_xr/test_iosxr.sh
new file mode 100755
index 000000000..632cfb201
--- /dev/null
+++ b/tests/test_cisco_xr/test_iosxr.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+echo "Starting tests...good luck:" \
+&& echo "Cisco IOS-XR (xrv)" \
+&& cd .. \
+&& py.test -s -x -v test_netmiko_show.py --test_device cisco_xrv \
+&& py.test -s -x -v test_netmiko_config.py --test_device cisco_xrv \
+&& py.test -v -s -x test_netmiko_config_acl.py --test_device cisco_xrv \
+&& py.test -s -x -v test_netmiko_commit.py --test_device cisco_xrv \
+&& py.test -s -x -v test_netmiko_scp.py --test_device cisco_xrv \
+&& py.test -s -x -v test_netmiko_autodetect.py --test_device cisco_xrv \
+|| RETURN_CODE=1
+
+exit $RETURN_CODE
diff --git a/tests/test_cisco_xr/test_iosxr_azure.sh b/tests/test_cisco_xr/test_iosxr_azure.sh
new file mode 100755
index 000000000..c5d2d5981
--- /dev/null
+++ b/tests/test_cisco_xr/test_iosxr_azure.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+RETURN_CODE=0
+
+echo "Starting tests...good luck:" \
+&& cd .. \
+&& echo "Cisco IOS-XR (Azure)" \
+&& py.test -s -x -v test_netmiko_show.py --test_device cisco_xr_azure \
+&& py.test -s -x -v test_netmiko_config.py --test_device cisco_xr_azure \
+&& py.test -s -x -v test_netmiko_commit.py --test_device cisco_xr_azure \
+&& py.test -s -x -v test_netmiko_autodetect.py --test_device cisco_xr_azure \
+\
+|| RETURN_CODE=1
+
+exit $RETURN_CODE
+
+# FIX - some issue with SCP to the IOS-XR in Azure?
+#&& py.test -s -x -v test_netmiko_scp.py --test_device cisco_xr_azure \
diff --git a/tests/test_cisco_xr/testx.txt b/tests/test_cisco_xr/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_cisco_xr/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_commit.sh b/tests/test_commit.sh
new file mode 100644
index 000000000..13fc96fa7
--- /dev/null
+++ b/tests/test_commit.sh
@@ -0,0 +1,7 @@
+for i in 1 2 3 4 5 6 7 8
+do
+ py.test -s -x -v test_netmiko_commit.py::test_confirm_delay --test_device cisco_xrv
+ if [ $? -ne 0 ]; then
+ break
+ fi
+done
diff --git a/tests/test_dell.sh b/tests/test_dell.sh
deleted file mode 100755
index ff77924bb..000000000
--- a/tests/test_dell.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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 dell_force10 \
-&& py.test -v test_netmiko_config.py --test_device dell_force10 \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_enterasys_switch.py b/tests/test_enterasys_switch.py
deleted file mode 100755
index 6a234db59..000000000
--- a/tests/test_enterasys_switch.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-'''
-This will run an ssh command successfully on an enterasys SSA and so SSH must
-be enabled on the device
-'''
-
-from __future__ import print_function
-from netmiko import ConnectHandler
-
-def main():
- '''
- This will run an ssh command successfully on an enterasys SSA and so SSH must
- be enabled on the device
- '''
- enterasyshandle = {
- 'device_type':'enterasys',
- 'ip' : '10.54.116.175',
- 'username':'admin',
- 'password':''}
- net_connect = ConnectHandler(**enterasyshandle)
- output = net_connect.send_command('show config policy')
- print(output)
-
-if __name__ == "__main__":
- main()
diff --git a/tests/test_extreme_exos/test9.txt b/tests/test_extreme_exos/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_extreme_exos/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_extreme_exos/testx.txt b/tests/test_extreme_exos/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_extreme_exos/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_extreme_switch.py b/tests/test_extreme_switch.py
deleted file mode 100755
index b6b27fe3c..000000000
--- a/tests/test_extreme_switch.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-'''
-This will run an ssh command successfully on an extreme switch and so SSH must
-be enabled on the device
-'''
-
-from __future__ import print_function
-from netmiko import ConnectHandler
-
-def main():
- '''
- This will run an ssh command successfully on an extreme switch and so SSH must
- be enabled on the device
- '''
- extremehandle = {
- 'device_type':'extreme',
- 'ip' : '10.54.116.175',
- 'username':'admin',
- 'password':''}
- net_connect = ConnectHandler(**extremehandle)
- output = net_connect.send_command('show config vlan')
- print(output)
-
-if __name__ == "__main__":
- main()
diff --git a/tests/test_hp.sh b/tests/test_hp.sh
deleted file mode 100755
index d430b696d..000000000
--- a/tests/test_hp.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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 hp_procurve \
-&& py.test -v test_netmiko_config.py --test_device hp_procurve \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_hp_comware.sh b/tests/test_hp_comware.sh
deleted file mode 100755
index 7c1ab85b9..000000000
--- a/tests/test_hp_comware.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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 hp_comware \
-&& py.test -v test_netmiko_config.py --test_device hp_comware \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_import_netmiko.py b/tests/test_import_netmiko.py
index 074055326..bf71c9212 100644
--- a/tests/test_import_netmiko.py
+++ b/tests/test_import_netmiko.py
@@ -1,4 +1,5 @@
-from netmiko import ConnectHandler
+from netmiko import ConnectHandler # noqa
+
def test_placeholder():
assert True
diff --git a/tests/test_iosxe.sh b/tests/test_iosxe.sh
deleted file mode 100755
index 53a44f7f0..000000000
--- a/tests/test_iosxe.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-echo "Starting tests...good luck:" \
-&& echo "Cisco IOS-XE" \
-&& py.test -v test_netmiko_show.py --test_device ios_xe \
-&& py.test -v test_netmiko_config.py --test_device ios_xe \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_iosxr.sh b/tests/test_iosxr.sh
deleted file mode 100755
index c0200702f..000000000
--- a/tests/test_iosxr.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Cisco IOS-XR" \
-&& py.test -v test_netmiko_show.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_config.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_commit.py --test_device cisco_xrv \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_juniper.sh b/tests/test_juniper.sh
deleted file mode 100755
index 16f515119..000000000
--- a/tests/test_juniper.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/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 juniper_srx \
-&& py.test -v test_netmiko_config.py --test_device juniper_srx \
-&& py.test -v test_netmiko_commit.py --test_device juniper_srx \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_juniper_junos/test9.txt b/tests/test_juniper_junos/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_juniper_junos/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_juniper_junos/test_juniper_junos.sh b/tests/test_juniper_junos/test_juniper_junos.sh
new file mode 100755
index 000000000..b09c3380a
--- /dev/null
+++ b/tests/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/test_juniper_junos/testx.txt b/tests/test_juniper_junos/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_juniper_junos/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_linux.py b/tests/test_linux.py
deleted file mode 100755
index 944c71a7b..000000000
--- a/tests/test_linux.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-from netmiko import ConnectHandler
-
-def main():
-
- try:
- hostname = raw_input("Enter remote host to test: ")
- username = raw_input("Enter remote username: ")
- except NameError:
- hostname = input("Enter remote host to test: ")
- username = input("Enter remote username: ")
-
- linux_test = {
- 'username': username,
- 'use_keys': True,
- 'ip': hostname,
- 'device_type': 'ovs_linux',
- 'key_file': '/home/{}/.ssh/test_rsa'.format(username),
- 'verbose': False}
-
- net_connect = ConnectHandler(**linux_test)
- print()
- print(net_connect.find_prompt())
-
- # Test enable mode
- print()
- print("***** Testing enable mode *****")
- net_connect.enable()
- if net_connect.check_enable_mode():
- print("Success: in enable mode")
- else:
- print("Fail...")
- print(net_connect.find_prompt())
-
- net_connect.exit_enable_mode()
- print("Out of enable mode")
- print(net_connect.find_prompt())
-
- # Test config mode
- print()
- print("***** Testing config mode *****")
- net_connect.config_mode()
- if net_connect.check_config_mode():
- print("Success: in config mode")
- else:
- print("Fail...")
- print(net_connect.find_prompt())
-
- net_connect.exit_config_mode()
- print("Out of config mode")
- print(net_connect.find_prompt())
-
- # Test config mode (when already at root prompt)
- print()
- print("***** Testing config mode when already root *****")
- net_connect.enable()
- if net_connect.check_enable_mode():
- print("Success: in enable mode")
- else:
- print("Fail...")
- print(net_connect.find_prompt())
- print("Test config_mode while already at root prompt")
- net_connect.config_mode()
- if net_connect.check_config_mode():
- print("Success: still at root prompt")
- else:
- print("Fail...")
- net_connect.exit_config_mode()
- # Should do nothing
- net_connect.exit_enable_mode()
- print("Out of config/enable mode")
- print(net_connect.find_prompt())
-
- # Send config commands
- print()
- print("***** Testing send_config_set *****")
- print(net_connect.find_prompt())
- output = net_connect.send_config_set(['ls -al'])
- print(output)
- print()
-
-if __name__ == "__main__":
- main()
diff --git a/tests/test_linux/test9.txt b/tests/test_linux/test9.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_linux/test9.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_linux/testx.txt b/tests/test_linux/testx.txt
new file mode 100644
index 000000000..acc8e3dd5
--- /dev/null
+++ b/tests/test_linux/testx.txt
@@ -0,0 +1 @@
+no logging console
diff --git a/tests/test_netmiko_autodetect.py b/tests/test_netmiko_autodetect.py
index 72cfb2f7c..7051ee14a 100755
--- a/tests/test_netmiko_autodetect.py
+++ b/tests/test_netmiko_autodetect.py
@@ -1,9 +1,4 @@
#!/usr/bin/env python
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-
-
def test_ssh_connect(ssh_autodetect):
"""Verify the connection was established successfully."""
net_conn, real_device_type = ssh_autodetect
diff --git a/tests/test_netmiko_cmd_verify.py b/tests/test_netmiko_cmd_verify.py
new file mode 100755
index 000000000..a7360b934
--- /dev/null
+++ b/tests/test_netmiko_cmd_verify.py
@@ -0,0 +1,55 @@
+import pytest
+from netmiko.utilities import select_cmd_verify
+
+
+@select_cmd_verify
+def bogus_func(obj, *args, **kwargs):
+ """Function that just returns the arguments modified by the decorator."""
+ return (obj, args, kwargs)
+
+
+def test_cmd_verify_decorator(net_connect_cmd_verify):
+ obj = net_connect_cmd_verify
+ # Global False should have precedence
+ assert obj.global_cmd_verify is False
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=True)
+ assert kwargs["cmd_verify"] is False
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=False)
+ assert kwargs["cmd_verify"] is False
+
+ # Global True should have precedence
+ obj.global_cmd_verify = True
+ assert obj.global_cmd_verify is True
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=True)
+ assert kwargs["cmd_verify"] is True
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=False)
+ assert kwargs["cmd_verify"] is True
+
+ # None should track the local argument
+ obj.global_cmd_verify = None
+ assert obj.global_cmd_verify is None
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=True)
+ assert kwargs["cmd_verify"] is True
+ (obj, args, kwargs) = bogus_func(net_connect_cmd_verify, cmd_verify=False)
+ assert kwargs["cmd_verify"] is False
+
+ # Set it back to proper False value (so later tests aren't messed up).
+ obj.global_cmd_verify = False
+
+
+def test_send_command_global_cmd_verify(
+ net_connect_cmd_verify, commands, expected_responses
+):
+ """
+ Verify a command can be sent down the channel successfully using send_command method.
+
+ Disable cmd_verify globally.
+ """
+ net_connect = net_connect_cmd_verify
+ if net_connect.fast_cli is True:
+ assert pytest.skip()
+ net_connect.clear_buffer()
+ # cmd_verify should be disabled globally at this point
+ assert net_connect.global_cmd_verify is False
+ show_ip_alt = net_connect.send_command(commands["basic"])
+ assert expected_responses["interface_ip"] in show_ip_alt
diff --git a/tests/test_netmiko_commit.py b/tests/test_netmiko_commit.py
index 22ee6bd86..4985f79e7 100755
--- a/tests/test_netmiko_commit.py
+++ b/tests/test_netmiko_commit.py
@@ -17,37 +17,48 @@
import re
import random
import string
+import pytest
+
def gen_random(N=6):
- return "".join([random.choice(string.ascii_lowercase + string.ascii_uppercase
- + string.digits) for x in range(N) ])
+ return "".join(
+ [
+ random.choice(
+ string.ascii_lowercase + string.ascii_uppercase + string.digits
+ )
+ for x in range(N)
+ ]
+ )
+
def retrieve_commands(commands):
"""
Retrieve context needed for a set of commit actions
"""
- config_commands = commands['config']
- support_commit = commands.get('support_commit')
- config_verify = commands['config_verification']
+ config_commands = commands["config"]
+ support_commit = commands.get("support_commit")
+ config_verify = commands["config_verification"]
return (config_commands, support_commit, config_verify)
+
def setup_initial_state(net_connect, commands, expected_responses):
- '''
+ """
Setup initial configuration prior to change so that config change can be verified
- '''
+ """
# Setup initial state
config_commands, support_commit, config_verify = retrieve_commands(commands)
setup_base_config(net_connect, config_commands[0:1])
- cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
+ cmd_response = expected_responses.get("cmd_response_init", config_commands[0])
initial_state = config_change_verify(net_connect, config_verify, cmd_response)
assert initial_state is True
return config_commands, support_commit, config_verify
+
def setup_base_config(net_connect, config_changes):
"""
Send set of config commands and commit
@@ -55,63 +66,72 @@ def setup_base_config(net_connect, config_changes):
net_connect.send_config_set(config_changes)
net_connect.commit()
+
def config_change_verify(net_connect, verify_cmd, cmd_response):
- '''
+ """
Send verify_cmd down channel, verify cmd_response in output
- '''
+ """
config_commands_output = net_connect.send_command_expect(verify_cmd)
if cmd_response in config_commands_output:
return True
else:
return False
+
def test_ssh_connect(net_connect, commands, expected_responses):
- '''
+ """
Verify the connection was established successfully
- '''
+ """
show_version = net_connect.send_command_expect(commands["version"])
assert expected_responses["version_banner"] in show_version
+
def test_config_mode(net_connect, commands, expected_responses):
- '''
+ """
Test enter config mode
- '''
+ """
net_connect.config_mode()
- assert net_connect.check_config_mode() == True
+ assert net_connect.check_config_mode() is True
+
def test_commit_base(net_connect, commands, expected_responses):
- '''
+ """
Test .commit() with no options
- '''
+ """
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
# Perform commit test
net_connect.send_config_set(config_commands)
net_connect.commit()
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
def test_commit_confirm(net_connect, commands, expected_responses):
- '''
+ """
Test confirm with confirm
- '''
+ """
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
+ if net_connect.device_type in ["nokia_sros"]:
+ assert pytest.skip()
# Perform commit-confirm test
net_connect.send_config_set(config_commands)
- if net_connect.device_type == 'cisco_xr':
+ if net_connect.device_type == "cisco_xr":
net_connect.commit(confirm=True, confirm_delay=60)
else:
net_connect.commit(confirm=True)
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
@@ -120,21 +140,25 @@ def test_commit_confirm(net_connect, commands, expected_responses):
def test_confirm_delay(net_connect, commands, expected_responses):
- '''
+ """
Test commit with confirm and non-default delay
- '''
+ """
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
+ if net_connect.device_type in ["nokia_sros"]:
+ assert pytest.skip()
# Perform commit-confirm test
net_connect.send_config_set(config_commands)
- if net_connect.device_type == 'cisco_xr':
+ if net_connect.device_type == "cisco_xr":
net_connect.commit(confirm=True, confirm_delay=60)
else:
net_connect.commit(confirm=True, confirm_delay=5)
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
@@ -143,31 +167,36 @@ def test_confirm_delay(net_connect, commands, expected_responses):
def test_no_confirm(net_connect, commands, expected_responses):
- '''
+ """
Perform commit-confirm, but don't confirm (verify rollback)
- '''
+ """
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
+ if net_connect.device_type in ["nokia_sros"]:
+ assert pytest.skip()
# Perform commit-confirm test
net_connect.send_config_set(config_commands)
- if net_connect.device_type == 'cisco_xr':
+ if net_connect.device_type == "cisco_xr":
net_connect.commit(confirm=True, confirm_delay=30)
else:
net_connect.commit(confirm=True, confirm_delay=1)
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
time.sleep(130)
# Verify rolled back to initial state
- cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
+ cmd_response = expected_responses.get("cmd_response_init", config_commands[0])
init_state = config_change_verify(net_connect, config_verify, cmd_response)
assert init_state is True
+
def test_clear_msg(net_connect, commands, expected_responses):
"""
IOS-XR generates the following message upon a failed commit
@@ -184,86 +213,95 @@ def test_clear_msg(net_connect, commands, expected_responses):
# Setup the initial config state
config_commands, support_commit, config_verify = retrieve_commands(commands)
- if net_connect.device_type == 'cisco_xr':
+ if net_connect.device_type == "cisco_xr":
output = net_connect.send_config_set(config_commands)
- output += net_connect.send_command_expect('commit', expect_string=r'Do you wish to')
- output += net_connect.send_command_expect('yes', auto_find_prompt=False)
- assert True is True
+ output += net_connect.send_command_expect(
+ "commit", expect_string=r"Do you wish to"
+ )
+ output += net_connect.send_command_expect("yes", auto_find_prompt=False)
+ assert True
+
def test_commit_check(net_connect, commands, expected_responses):
- '''
+ """
Test commit check
- '''
+ """
# IOS-XR does not support commit check
- if net_connect.device_type == 'cisco_xr':
- assert True is True
+ if net_connect.device_type in ["cisco_xr", "nokia_sros"]:
+ assert pytest.skip()
else:
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
-
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
# Perform commit-confirm test
net_connect.send_config_set(config_commands)
net_connect.commit(check=True)
-
+
# Verify at initial state
- cmd_response = expected_responses.get('cmd_response_init', config_commands[0])
+ cmd_response = expected_responses.get("cmd_response_init", config_commands[0])
init_state = config_change_verify(net_connect, config_verify, cmd_response)
assert init_state is True
-
- rollback = commands.get('rollback')
+
+ rollback = commands.get("rollback")
net_connect.send_config_set([rollback])
def test_commit_comment(net_connect, commands, expected_responses):
- '''
+ """
Test commit with comment
- '''
+ """
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
+ if net_connect.device_type in ["nokia_sros"]:
+ assert pytest.skip()
# Perform commit with comment
net_connect.send_config_set(config_commands)
net_connect.commit(comment="Unit test on commit with comment")
# Verify change was committed
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
# Verify commit comment
commit_verification = commands.get("commit_verification")
tmp_output = net_connect.send_command(commit_verification)
- if net_connect.device_type == 'cisco_xr':
+ if net_connect.device_type == "cisco_xr":
commit_comment = tmp_output
else:
- commit_comment = tmp_output.split("\n")[2]
+ commit_comment = tmp_output.strip().split("\n")[1]
assert expected_responses.get("commit_comment") in commit_comment.strip()
def test_commit_andquit(net_connect, commands, expected_responses):
- '''
+ """
Test commit and immediately quit configure mode
- '''
+ """
# IOS-XR does not support commit and quit
- if net_connect.device_type == 'cisco_xr':
- assert True is True
+ if net_connect.device_type in ["cisco_xr", "nokia_sros"]:
+ assert pytest.skip()
else:
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
-
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
# Execute change and commit
net_connect.send_config_set(config_commands)
net_connect.commit(and_quit=True)
-
+
# Verify change was committed
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
- config_verify = 'show configuration | match archive'
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
+ config_verify = "show configuration | match archive"
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
@@ -271,18 +309,19 @@ def test_commit_andquit(net_connect, commands, expected_responses):
def test_commit_label(net_connect, commands, expected_responses):
"""Test commit label for IOS-XR."""
- if net_connect.device_type != 'cisco_xr':
+ if net_connect.device_type != "cisco_xr":
assert True is True
else:
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
-
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
# Execute change and commit
net_connect.send_config_set(config_commands)
label = "test_lbl_" + gen_random()
net_connect.commit(label=label)
-
+
# Verify commit label
commit_verification = commands.get("commit_verification")
tmp_output = net_connect.send_command(commit_verification)
@@ -293,23 +332,24 @@ def test_commit_label(net_connect, commands, expected_responses):
def test_commit_label_comment(net_connect, commands, expected_responses):
- '''
+ """
Test commit label for IOS-XR with comment
- '''
- # IOS-XR only test
- if net_connect.device_type != 'cisco_xr':
- assert True is True
+ """
+ # IOS-XR only test
+ if net_connect.device_type != "cisco_xr":
+ assert pytest.skip()
else:
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
-
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
# Execute change and commit
net_connect.send_config_set(config_commands)
label = "test_lbl_" + gen_random()
- comment="Test with comment and label"
+ comment = "Test with comment and label"
net_connect.commit(label=label, comment=comment)
-
+
# Verify commit label
commit_verification = commands.get("commit_verification")
tmp_output = net_connect.send_command(commit_verification)
@@ -325,23 +365,24 @@ def test_commit_label_comment(net_connect, commands, expected_responses):
def test_commit_label_confirm(net_connect, commands, expected_responses):
- '''
+ """
Test commit label for IOS-XR with confirm
- '''
- # IOS-XR only test
- if net_connect.device_type != 'cisco_xr':
- assert True is True
+ """
+ # IOS-XR only test
+ if net_connect.device_type != "cisco_xr":
+ assert pytest.skip()
else:
# Setup the initial config state
- config_commands, support_commit, config_verify = setup_initial_state(net_connect,
- commands, expected_responses)
-
+ config_commands, support_commit, config_verify = setup_initial_state(
+ net_connect, commands, expected_responses
+ )
+
# Execute change and commit
net_connect.send_config_set(config_commands)
label = "test_lbl_" + gen_random()
net_connect.commit(label=label, confirm=True, confirm_delay=120)
-
- cmd_response = expected_responses.get('cmd_response_final', config_commands[-1])
+
+ cmd_response = expected_responses.get("cmd_response_final", config_commands[-1])
final_state = config_change_verify(net_connect, config_verify, cmd_response)
assert final_state is True
@@ -357,17 +398,16 @@ def test_commit_label_confirm(net_connect, commands, expected_responses):
def test_exit_config_mode(net_connect, commands, expected_responses):
- '''
+ """
Test exit config mode
- '''
+ """
net_connect.exit_config_mode()
time.sleep(1)
- assert net_connect.check_config_mode() == False
+ assert net_connect.check_config_mode() is False
def test_disconnect(net_connect, commands, expected_responses):
- '''
+ """
Terminate the SSH session
- '''
+ """
net_connect.disconnect()
-
diff --git a/tests/test_netmiko_config.py b/tests/test_netmiko_config.py
index 275e3e96d..7ffabe872 100755
--- a/tests/test_netmiko_config.py
+++ b/tests/test_netmiko_config.py
@@ -1,85 +1,72 @@
#!/usr/bin/env python
-"""
-This module runs tests against Cisco IOS devices.
-
-setup_module: setup variables for later use.
-
-test_ssh_connect: verify ssh connectivity
-test_enable_mode: verify enter enable mode
-test_config_mode: verify enter config mode
-test_exit_config_mode: verify exit config mode
-test_command_set: verify sending a set of config commands
-test_commands_from_file: verify sending a set of config commands from a file
-test_disconnect: cleanly disconnect the SSH session
-
-"""
-
-from __future__ import print_function
-from __future__ import unicode_literals
+import pytest
+from netmiko import ConfigInvalidException
+from netmiko import ReadTimeout
def test_ssh_connect(net_connect, commands, expected_responses):
- '''
+ """
Verify the connection was established successfully
- '''
+ """
show_version = net_connect.send_command(commands["version"])
assert expected_responses["version_banner"] in show_version
def test_enable_mode(net_connect, commands, expected_responses):
- '''
+ """
Test entering enable mode
Catch exception for devices that don't support enable
- '''
+ """
try:
net_connect.enable()
enable_prompt = net_connect.find_prompt()
- assert enable_prompt == expected_responses['enable_prompt']
+ assert enable_prompt == expected_responses["enable_prompt"]
except AttributeError:
- assert True == True
+ assert True
def test_config_mode(net_connect, commands, expected_responses):
- '''
+ """
Test enter config mode
- '''
- net_connect.config_mode()
- assert net_connect.check_config_mode() == True
+ """
+ # Behavior for devices with no config mode is to return null string
+ if net_connect.config_mode() != "":
+ assert net_connect.check_config_mode() is True
+ else:
+ 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() == 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_command_set(net_connect, commands, expected_responses):
+
+def test_config_set(net_connect, commands, expected_responses):
"""Test sending configuration commands."""
- config_commands = commands['config']
- support_commit = commands.get('support_commit')
- config_verify = commands['config_verification']
+
+ config_commands = commands["config"]
+ support_commit = commands.get("support_commit")
+ config_verify = commands["config_verification"]
# Set to initial value and testing sending command as a string
net_connect.send_config_set(config_commands[0])
if support_commit:
net_connect.commit()
-
- cmd_response = expected_responses.get('cmd_response_init')
+ cmd_response = expected_responses.get("cmd_response_init")
config_commands_output = net_connect.send_command(config_verify)
- print(config_verify)
- print(config_commands_output)
if cmd_response:
assert cmd_response in config_commands_output
else:
assert config_commands[0] in config_commands_output
-
net_connect.send_config_set(config_commands)
if support_commit:
net_connect.commit()
-
- cmd_response = expected_responses.get('cmd_response_final')
+ cmd_response = expected_responses.get("cmd_response_final")
config_commands_output = net_connect.send_command_expect(config_verify)
if cmd_response:
assert cmd_response in config_commands_output
@@ -87,24 +74,150 @@ def test_command_set(net_connect, commands, expected_responses):
assert config_commands[-1] in config_commands_output
-def test_commands_from_file(net_connect, commands, expected_responses):
- '''
+def test_config_set_longcommand(net_connect, commands, expected_responses):
+ """Test sending configuration commands using long commands"""
+ config_commands = commands.get("config_long_command")
+ config_verify = commands["config_verification"] # noqa
+ if not config_commands:
+ assert True
+ return
+ output = net_connect.send_config_set(config_commands) # noqa
+ assert True
+
+
+def test_config_hostname(net_connect, commands, expected_responses):
+ hostname = "test-netmiko1"
+ command = f"hostname {hostname}"
+ if "arista" in net_connect.device_type:
+ current_hostname = net_connect.find_prompt()[:-1]
+ 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):
+ """
Test sending configuration commands from a file
- '''
- config_file = commands.get('config_file')
- config_verify = commands['config_verification']
+ """
+ config_file = commands.get("config_file")
+ config_verify = commands["config_verification"]
if config_file is not None:
net_connect.send_config_from_file(config_file)
config_commands_output = net_connect.send_command_expect(config_verify)
assert expected_responses["file_check_cmd"] in config_commands_output
else:
- print("Skipping test (no file specified)...",)
+ assert pytest.skip()
+
+ if "nokia_sros" in net_connect.device_type:
+ net_connect.save_config()
+
+
+def test_config_error_pattern(net_connect, commands, expected_responses):
+ """
+ Raise exception when config_error_str is present in output
+ """
+ error_pattern = commands.get("error_pattern")
+ if error_pattern is None:
+ pytest.skip("No error_pattern defined.")
+ config_base = commands.get("config")
+ config_err = commands.get("invalid_config")
+ config_list = config_base + [config_err]
+
+ # Should not raise an exception since error_pattern not specified
+ net_connect.send_config_set(config_commands=config_list)
+
+ if config_list and error_pattern:
+ with pytest.raises(ConfigInvalidException):
+ net_connect.send_config_set(
+ config_commands=config_list, error_pattern=error_pattern
+ )
+
+ # Try it with cmd_verify=True also
+ with pytest.raises(ConfigInvalidException):
+ 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_banner(net_connect, commands, expected_responses):
+ """
+ Banner configuration has a special exclusing where cmd_verify is dynamically
+ disabled so make sure it works.
+ """
+ # Make sure banner comes in as separate lines
+ banner = commands.get("banner")
+ if banner is None:
+ pytest.skip("No banner defined.")
+ # Make sure banner comes in as separate lines
+ banner = banner.splitlines()
+ config_base = commands.get("config")
+ config_list = config_base + banner
+
+ # Remove any existing banner
+ net_connect.send_config_set("no banner login")
+
+ # bypass_commands="" should fail as cmd_verify will be True
+ with pytest.raises(ReadTimeout) as e: # noqa
+ net_connect.send_config_set(config_commands=config_list, bypass_commands="")
+
+ # Recover from send_config_set failure. The "%" is to finish the failed banner.
+ net_connect.write_channel("%\n")
+ net_connect.exit_config_mode()
+
+ net_connect.send_config_set(config_commands=config_list)
+ show_run = net_connect.send_command("show run | inc banner log")
+ assert "banner login" in show_run
+
+ net_connect.send_config_set("no banner login")
+
+
+def test_global_cmd_verify(net_connect, commands, expected_responses):
+ """
+ Banner configuration has a special exclusing where cmd_verify is dynamically
+ disabled so make sure it works.
+ """
+
+ # Make sure banner comes in as separate lines
+ banner = commands.get("banner")
+ if banner is None:
+ pytest.skip("No banner defined.")
+ # Make sure banner comes in as separate lines
+ banner = banner.splitlines()
+ config_base = commands.get("config")
+ config_list = config_base + banner
+
+ # Remove any existing banner
+ net_connect.send_config_set("no banner login")
+
+ # bypass_commands="" should fail as cmd_verify will be True
+ with pytest.raises(ReadTimeout) as e: # noqa
+ net_connect.send_config_set(config_commands=config_list, bypass_commands="")
+
+ # Recover from send_config_set failure. The "%" is to finish the failed banner.
+ net_connect.write_channel("%\n")
+ net_connect.exit_config_mode()
+
+ net_connect.global_cmd_verify = False
+ # Should work now as global_cmd_verify is False
+ net_connect.send_config_set(config_commands=config_list, bypass_commands="")
+ show_run = net_connect.send_command("show run | inc banner log")
+ assert "banner login" in show_run
+
+ net_connect.send_config_set("no banner login")
def test_disconnect(net_connect, commands, expected_responses):
- '''
+ """
Terminate the SSH session
- '''
+ """
net_connect.disconnect()
-
-
diff --git a/tests/test_netmiko_config_acl.py b/tests/test_netmiko_config_acl.py
new file mode 100755
index 000000000..ab61a689e
--- /dev/null
+++ b/tests/test_netmiko_config_acl.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+import re
+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
+
+
+def remove_acl(net_connect, cmd, commit=False):
+ """Ensure ACL is removed."""
+ net_connect.send_config_set(cmd)
+ if commit:
+ net_connect.commit()
+ net_connect.exit_config_mode()
+
+
+def test_large_acl(net_connect, commands, expected_responses, acl_entries=100):
+ """Test configuring a large ACL."""
+ if commands.get("config_long_acl"):
+ 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")
+
+ if "juniper_junos" in platform or "cisco_asa" 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()
+ else:
+ func_name = f"generate_{platform}_acl"
+ acl_func = globals()[func_name]
+ cfg_lines = acl_func()
+
+ # Send ACL to remote devices
+ result = net_connect.send_config_set(cfg_lines)
+ if support_commit:
+ net_connect.commit()
+ net_connect.exit_config_mode()
+
+ # send_config_set should return same num lines + offset lines for entering/exiting cfg-mode
+ # NX-OS is will have more than one newline (per line)
+ result_list = re.split(r"\n+", result)
+ 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, read_timeout=90)
+ verify_list = re.split(r"\n+", verify.strip())
+
+ # IOS-XR potentially has a timestamp on the show command
+ if "UTC" in verify_list[0]:
+ verify_list.pop(0)
+ 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 or "cisco_asa" in platform:
+ cmd = delete_cmd
+ else:
+ cmd = f"no {base_cmd}"
+ remove_acl(net_connect, cmd=cmd, commit=support_commit)
+ net_connect.disconnect()
diff --git a/tests/test_netmiko_exceptions.py b/tests/test_netmiko_exceptions.py
new file mode 100644
index 000000000..761135593
--- /dev/null
+++ b/tests/test_netmiko_exceptions.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+from os import path
+from datetime import datetime
+import pytest
+from netmiko import ConnectHandler
+from netmiko import NetmikoTimeoutException
+from test_utils import parse_yaml
+
+PWD = path.dirname(path.realpath(__file__))
+DEVICE_DICT = parse_yaml(PWD + "/etc/test_devices_exc.yml")
+
+
+def test_valid_conn():
+ """Verify device without modifications works."""
+ device = DEVICE_DICT["cisco3_invalid"]
+ conn = ConnectHandler(**device)
+ assert conn.find_prompt() == "cisco3#"
+
+
+def test_invalid_port():
+ device = DEVICE_DICT["cisco3_invalid"]
+ device["port"] = 8022
+ with pytest.raises(NetmikoTimeoutException):
+ ConnectHandler(**device)
+
+
+def test_conn_timeout():
+ device = DEVICE_DICT["cisco3_invalid"]
+ device["conn_timeout"] = 5
+ device["port"] = 8022
+ start_time = datetime.now()
+ with pytest.raises(NetmikoTimeoutException):
+ ConnectHandler(**device)
+ end_time = datetime.now()
+ time_delta = end_time - start_time
+ assert time_delta.total_seconds() > 5.0
+ assert time_delta.total_seconds() < 5.1
+
+
+def test_dns_fail():
+ device = DEVICE_DICT["cisco3_invalid"]
+ device["host"] = "invalid.lasthop.io"
+ with pytest.raises(NetmikoTimeoutException):
+ try:
+ ConnectHandler(**device)
+ except NetmikoTimeoutException as e:
+ assert "DNS failure" in str(e)
+ raise
+
+
+def test_dns_fail_timeout():
+ """Should fail very fast."""
+ device = DEVICE_DICT["cisco3_invalid"]
+ device["host"] = "invalid.lasthop.io"
+ start_time = datetime.now()
+ with pytest.raises(NetmikoTimeoutException):
+ try:
+ ConnectHandler(**device)
+ except NetmikoTimeoutException as e:
+ assert "DNS failure" in str(e)
+ raise
+ end_time = datetime.now()
+ time_delta = end_time - start_time
+ assert time_delta.total_seconds() < 0.1
+
+
+def test_auth_timeout():
+ assert True
+
+
+def test_banner_timeout():
+ assert True
diff --git a/tests/test_netmiko_save.py b/tests/test_netmiko_save.py
new file mode 100755
index 000000000..00b051efd
--- /dev/null
+++ b/tests/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()
diff --git a/tests/test_netmiko_scp.py b/tests/test_netmiko_scp.py
index ad5c938fb..b843095d4 100755
--- a/tests/test_netmiko_scp.py
+++ b/tests/test_netmiko_scp.py
@@ -1,25 +1,7 @@
#!/usr/bin/env python
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-import sys
-import os
import pytest
-from datetime import datetime
-from getpass import getpass
-from netmiko import ConnectHandler, FileTransfer
from netmiko import file_transfer
-###def test_enable_scp(scp_fixture):
-### ssh_conn, scp_transfer = scp_fixture
-###
-### scp_transfer.disable_scp()
-### output = ssh_conn.send_command_expect("show run | inc scp")
-### assert 'ip scp server enable' not in output
-###
-### scp_transfer.enable_scp()
-### output = ssh_conn.send_command_expect("show run | inc scp")
-### assert 'ip scp server enable' in output
def test_scp_put(scp_fixture):
ssh_conn, scp_transfer = scp_fixture
@@ -27,24 +9,28 @@ def test_scp_put(scp_fixture):
assert False
else:
scp_transfer.put_file()
- assert scp_transfer.check_file_exists() == True
+ assert scp_transfer.check_file_exists() is True
+
def test_remote_space_available(scp_fixture, expected_responses):
ssh_conn, scp_transfer = scp_fixture
remote_space = scp_transfer.remote_space_available()
assert remote_space >= expected_responses["scp_remote_space"]
-
+
+
def test_local_space_available(scp_fixture):
ssh_conn, scp_transfer = scp_fixture
local_space = scp_transfer.local_space_available()
- assert local_space >= 1000000000
-
+ assert local_space >= 1_000_000_000
+
+
def test_verify_space_available_put(scp_fixture):
ssh_conn, scp_transfer = scp_fixture
- assert scp_transfer.verify_space_available() == True
+ assert scp_transfer.verify_space_available() is True
# intentional make there not be enough space available
- scp_transfer.file_size = 10000000000
- assert scp_transfer.verify_space_available() == False
+ scp_transfer.file_size = 100_000_000_000
+ assert scp_transfer.verify_space_available() is False
+
def test_remote_file_size(scp_fixture):
ssh_conn, scp_transfer = scp_fixture
@@ -53,25 +39,31 @@ def test_remote_file_size(scp_fixture):
remote_file_size = scp_transfer.remote_file_size()
assert remote_file_size == 19
+
def test_md5_methods(scp_fixture):
ssh_conn, scp_transfer = scp_fixture
- md5_value = 'd8df36973ff832b564ad84642d07a261'
+ if "nokia_sros" in ssh_conn.device_type or "extreme_exos" in ssh_conn.device_type:
+ pytest.skip("MD5 not supported on this platform")
+ md5_value = "d8df36973ff832b564ad84642d07a261"
remote_md5 = scp_transfer.remote_md5()
assert remote_md5 == md5_value
- assert scp_transfer.compare_md5() == True
+ assert scp_transfer.compare_md5() is True
+
def test_disconnect(scp_fixture):
"""Terminate the SSH session."""
ssh_conn, scp_transfer = scp_fixture
ssh_conn.disconnect()
+
def test_verify_space_available_get(scp_fixture_get):
ssh_conn, scp_transfer = scp_fixture_get
- assert scp_transfer.verify_space_available() == True
+ assert scp_transfer.verify_space_available() is True
# intentional make there not be enough space available
- scp_transfer.file_size = 100000000000
- assert scp_transfer.verify_space_available() == False
+ scp_transfer.file_size = 100_000_000_000_000_000
+ assert scp_transfer.verify_space_available() is False
+
def test_scp_get(scp_fixture_get):
ssh_conn, scp_transfer = scp_fixture_get
@@ -86,12 +78,17 @@ def test_scp_get(scp_fixture_get):
else:
assert False
+
def test_md5_methods_get(scp_fixture_get):
ssh_conn, scp_transfer = scp_fixture_get
- md5_value = 'd8df36973ff832b564ad84642d07a261'
- local_md5 = scp_transfer.file_md5("test9.txt")
+ platform = ssh_conn.device_type
+ if "nokia_sros" in ssh_conn.device_type or "extreme_exos" in ssh_conn.device_type:
+ pytest.skip("MD5 not supported on this platform")
+ md5_value = "d8df36973ff832b564ad84642d07a261"
+ local_md5 = scp_transfer.file_md5(f"test_{platform}/test9.txt")
assert local_md5 == md5_value
- assert scp_transfer.compare_md5() == True
+ assert scp_transfer.compare_md5() is True
+
def test_disconnect_get(scp_fixture_get):
"""Terminate the SSH session."""
@@ -102,97 +99,171 @@ def test_disconnect_get(scp_fixture_get):
def test_file_transfer(scp_file_transfer):
"""Test Netmiko file_transfer function."""
ssh_conn, file_system = scp_file_transfer
- source_file = 'test9.txt'
- dest_file = 'test9.txt'
- direction = 'put'
- print(file_system)
+ platform = ssh_conn.device_type
+ source_file = f"test_{platform}/test9.txt"
+ dest_file = "test9.txt"
+ direction = "put"
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file,
- file_system=file_system, direction=direction,
- overwrite_file=True)
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
# No file on device at the beginning
- assert transfer_dict['file_exists'] and transfer_dict['file_transferred'] and transfer_dict['file_verified']
+ assert (
+ transfer_dict["file_exists"]
+ and transfer_dict["file_transferred"]
+ and transfer_dict["file_verified"]
+ )
# File exists on device at this point
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file,
- file_system=file_system, direction=direction,
- overwrite_file=True)
- assert transfer_dict['file_exists'] and not transfer_dict['file_transferred'] and transfer_dict['file_verified']
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
+ assert (
+ transfer_dict["file_exists"]
+ and not transfer_dict["file_transferred"]
+ and transfer_dict["file_verified"]
+ )
# Don't allow a file overwrite (switch the source file, but same dest file name)
- source_file = 'test2_src.txt'
+ source_file = f"test_{platform}/test2_src.txt"
with pytest.raises(Exception):
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file,
- file_system=file_system, direction=direction,
- overwrite_file=False)
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=False,
+ )
# Don't allow MD5 and file overwrite not allowed
- source_file = 'test9.txt'
+ source_file = f"test_{platform}/test9.txt"
with pytest.raises(Exception):
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=True,
- file_system=file_system, direction=direction,
- overwrite_file=False)
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=True,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=False,
+ )
# Don't allow MD5 (this will force a re-transfer)
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=True,
- file_system=file_system, direction=direction,
- overwrite_file=True)
- assert transfer_dict['file_exists'] and transfer_dict['file_transferred'] and not transfer_dict['file_verified']
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=True,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
+ assert (
+ transfer_dict["file_exists"]
+ and transfer_dict["file_transferred"]
+ and not transfer_dict["file_verified"]
+ )
# Transfer 'test2.txt' in preparation for get operations
- source_file = 'test2_src.txt'
- dest_file = 'test2.txt'
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file,
- file_system=file_system, direction=direction,
- overwrite_file=True)
- assert transfer_dict['file_exists']
+ source_file = "test2_src.txt"
+ dest_file = "test2.txt"
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
+ assert transfer_dict["file_exists"]
# GET Operations
- direction = 'get'
- source_file = 'test9.txt'
- dest_file = 'testx.txt'
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=False,
- file_system=file_system, direction=direction,
- overwrite_file=True)
+ direction = "get"
+ source_file = "test9.txt"
+ dest_file = f"test_{platform}/testx.txt"
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=False,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
# File get should occur here
- assert transfer_dict['file_exists'] and transfer_dict['file_transferred'] and transfer_dict['file_verified']
+ assert (
+ transfer_dict["file_exists"]
+ and transfer_dict["file_transferred"]
+ and transfer_dict["file_verified"]
+ )
# File should exist now
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=False,
- file_system=file_system, direction=direction,
- overwrite_file=True)
- assert transfer_dict['file_exists'] and not transfer_dict['file_transferred'] and transfer_dict['file_verified']
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=False,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
+ assert (
+ transfer_dict["file_exists"]
+ and not transfer_dict["file_transferred"]
+ and transfer_dict["file_verified"]
+ )
# Don't allow a file overwrite (switch the file, but same dest file name)
- source_file = 'test2.txt'
- dest_file = 'testx.txt'
+ source_file = f"test_{platform}/test2.txt"
+ dest_file = f"test_{platform}/testx.txt"
with pytest.raises(Exception):
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file,
- file_system=file_system, direction=direction,
- overwrite_file=False)
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=False,
+ )
# Don't allow MD5 and file overwrite not allowed
- source_file = 'test9.txt'
- dest_file = 'testx.txt'
+ source_file = "test9.txt"
+ dest_file = f"test_{platform}/testx.txt"
with pytest.raises(Exception):
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=True,
- file_system=file_system, direction=direction,
- overwrite_file=False)
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=True,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=False,
+ )
# Don't allow MD5 (this will force a re-transfer)
- transfer_dict = file_transfer(ssh_conn, source_file=source_file,
- dest_file=dest_file, disable_md5=True,
- file_system=file_system, direction=direction,
- overwrite_file=True)
- assert transfer_dict['file_exists'] and transfer_dict['file_transferred'] and not transfer_dict['file_verified']
+ transfer_dict = file_transfer(
+ ssh_conn,
+ source_file=source_file,
+ dest_file=dest_file,
+ disable_md5=True,
+ file_system=file_system,
+ direction=direction,
+ overwrite_file=True,
+ )
+ assert (
+ transfer_dict["file_exists"]
+ and transfer_dict["file_transferred"]
+ and not transfer_dict["file_verified"]
+ )
diff --git a/tests/test_netmiko_session_log.py b/tests/test_netmiko_session_log.py
new file mode 100644
index 000000000..c9a54b93f
--- /dev/null
+++ b/tests/test_netmiko_session_log.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python
+import time
+import hashlib
+import io
+import logging
+from netmiko import ConnectHandler
+
+
+def calc_md5(file_name=None, contents=None):
+ """Compute MD5 hash of file."""
+ if contents is not None:
+ pass
+ elif file_name:
+ with open(file_name, "rb") as f:
+ contents = f.read()
+ else:
+ raise ValueError("Most specify either file_name or contents")
+
+ return hashlib.md5(contents.strip()).hexdigest()
+
+
+def read_session_log(session_file, append=False):
+ """Leading white-space can vary. Strip off leading white-space."""
+ with open(session_file, "rb") as f:
+ if append is True:
+ line = f.readline().decode()
+ assert "Initial file contents" in line
+ log_content = f.read().lstrip()
+ return log_content
+
+
+def session_action(my_connect, command):
+ """Common actions in the netmiko session to generate the session log."""
+ time.sleep(1)
+ my_connect.clear_buffer()
+ output = my_connect.send_command(command)
+ my_connect.disconnect()
+ return output
+
+
+def session_log_md5(session_file, compare_file):
+ """Compare the session_log MD5 to the compare_file MD5"""
+ compare_log_md5 = calc_md5(file_name=compare_file)
+ log_content = read_session_log(session_file)
+ session_log_md5 = calc_md5(contents=log_content)
+ assert session_log_md5 == compare_log_md5
+
+
+def session_log_md5_append(session_file, compare_file):
+ """Compare the session_log MD5 to the compare_file MD5"""
+ compare_log_md5 = calc_md5(file_name=compare_file)
+ log_content = read_session_log(session_file, append=True)
+ session_log_md5 = calc_md5(contents=log_content)
+ assert session_log_md5 == compare_log_md5
+
+
+def test_session_log(net_connect, commands, expected_responses):
+ """Verify session_log matches expected content."""
+ command = commands["basic"]
+ session_action(net_connect, command)
+
+ compare_file = expected_responses["compare_log"]
+ session_file = expected_responses["session_log"]
+
+ session_log_md5(session_file, compare_file)
+
+
+def test_session_log_write(net_connect_slog_wr, commands, expected_responses):
+ """Verify session_log matches expected content, but when channel writes are also logged."""
+ command = commands["basic"]
+ nc = net_connect_slog_wr
+
+ # Send a marker down the channel
+ nc.send_command("show foooooooo")
+ time.sleep(1)
+ nc.clear_buffer()
+ nc.send_command(command)
+ nc.disconnect()
+
+ compare_file = expected_responses["compare_log_wr"]
+ session_file = expected_responses["session_log_wr"]
+
+ with open(compare_file, "rb") as f:
+ compare_contents = f.read()
+
+ # Header information varies too much due to device behavior differences.
+ # So just discard it.
+ marker = b"% Invalid input detected at '^' marker."
+ _, compare_contents = compare_contents.split(marker)
+ compare_log_md5 = calc_md5(contents=compare_contents.strip())
+
+ log_content = read_session_log(session_file)
+ marker = b"% Invalid input detected at '^' marker."
+ _, log_content = log_content.split(marker)
+
+ session_log_md5 = calc_md5(contents=log_content.strip())
+ assert session_log_md5 == compare_log_md5
+
+
+def test_session_log_append(device_slog, commands, expected_responses):
+ """Verify session_log matches expected content, but when channel writes are also logged."""
+ session_file = expected_responses["session_log_append"]
+ # Create a starting file
+ with open(session_file, "wb") as f:
+ f.write(b"Initial file contents\n\n")
+
+ # The netmiko connection has not been established yet.
+ device_slog["session_log"] = session_file
+
+ conn = ConnectHandler(**device_slog)
+ command = commands["basic"]
+ session_action(conn, command)
+
+ compare_file = expected_responses["compare_log_append"]
+ session_log_md5_append(session_file, compare_file)
+
+
+def test_session_log_secrets(device_slog):
+ """Verify session_log does not contain password or secret."""
+ conn = ConnectHandler(**device_slog)
+ conn.session_log.write("\nTesting password and secret replacement\n")
+ conn.session_log.write("This is my password {}\n".format(conn.password))
+ conn.session_log.write("This is my secret {}\n".format(conn.secret))
+
+ file_name = device_slog["session_log"]
+ with open(file_name, "r") as f:
+ session_log = f.read()
+ if conn.password:
+ assert conn.password not in session_log
+ if conn.secret:
+ assert conn.secret not in session_log
+
+
+def test_logging_filter_secrets(net_connect_slog_wr):
+ """Verify logging DEBUG output does not contain password or secret."""
+
+ nc = net_connect_slog_wr
+
+ # setup logger to output to file
+ file_name = "SLOG/netmiko.log"
+ netmikologger = logging.getLogger("netmiko")
+ netmikologger.setLevel(logging.DEBUG)
+ file_handler = logging.FileHandler(file_name)
+ file_handler.setLevel(logging.DEBUG)
+ netmikologger.addHandler(file_handler)
+
+ # cleanup the log file
+ with open(file_name, "w") as f:
+ f.write("")
+
+ # run sequence
+ nc.enable()
+ time.sleep(1)
+ nc.clear_buffer()
+ nc.disconnect()
+
+ with open(file_name, "r") as f:
+ netmiko_log = f.read()
+ if nc.password:
+ assert nc.password not in netmiko_log
+ if nc.secret:
+ assert nc.secret not in netmiko_log
+
+
+def test_unicode(device_slog):
+ """Verify that you can write unicode characters into the session_log."""
+ conn = ConnectHandler(**device_slog)
+
+ smiley_face = "\N{grinning face with smiling eyes}"
+ conn.session_log.write("\nTesting unicode\n")
+ conn.session_log.write(smiley_face)
+ conn.session_log.write(smiley_face)
+
+ file_name = device_slog["session_log"]
+ with open(file_name, "r") as f:
+ session_log = f.read()
+ assert smiley_face in session_log
+
+
+def test_session_log_bytesio(device_slog, commands, expected_responses):
+ """Verify session_log matches expected content, but when channel writes are also logged."""
+ s_log = io.BytesIO()
+
+ # The netmiko connection has not been established yet.
+ device_slog["session_log"] = s_log
+ device_slog["session_log_file_mode"] = "write"
+
+ conn = ConnectHandler(**device_slog)
+ command = commands["basic"]
+ session_action(conn, command)
+
+ compare_file = expected_responses["compare_log"]
+ compare_log_md5 = calc_md5(file_name=compare_file)
+
+ log_content = s_log.getvalue()
+ session_log_md5 = calc_md5(contents=log_content)
+ assert session_log_md5 == compare_log_md5
diff --git a/tests/test_netmiko_show.py b/tests/test_netmiko_show.py
index 9f9b7c416..1bbcfafa0 100755
--- a/tests/test_netmiko_show.py
+++ b/tests/test_netmiko_show.py
@@ -5,7 +5,7 @@
test_disable_paging: disable paging
test_ssh_connect: verify ssh connectivity
test_send_command: send a command
-test_send_command_expect: send a command
+test_send_command_timing: send a command
test_base_prompt: test the base prompt
test_strip_prompt: test removing the prompt
test_strip_command: test stripping extraneous info after sending a command
@@ -14,98 +14,367 @@
test_enable_mode: verify enter enable mode
test_disconnect: cleanly disconnect the SSH session
"""
-
-from __future__ import print_function
-from __future__ import unicode_literals
+import pytest
import time
+from datetime import datetime
def test_disable_paging(net_connect, commands, expected_responses):
"""Verify paging is disabled by looking for string after when paging would normally occur."""
- if net_connect.device_type == 'arista_eos':
+
+ if net_connect.device_type == "arista_eos":
# Arista logging buffer gets enormous
- net_connect.send_command_expect('clear logging')
- multiple_line_output = net_connect.send_command_expect(commands["extended_output"])
+ net_connect.send_command("clear logging")
+ elif net_connect.device_type == "arista_eos":
+ # NX-OS logging buffer gets enormous (NX-OS fails when testing very high-latency +
+ # packet loss)
+ net_connect.send_command("clear logging logfile")
+ multiple_line_output = net_connect.send_command(
+ commands["extended_output"], read_timeout=60
+ )
assert expected_responses["multiple_line_output"] in multiple_line_output
- if net_connect.device_type == 'arista_eos':
- # Arista output is slow and has router-name in output
- time.sleep(5)
- net_connect.clear_buffer()
- net_connect.send_command_expect('clear logging', expect_string='#')
+
+
+def test_terminal_width(net_connect, commands, expected_responses):
+ """Verify long commands work properly."""
+ wide_command = commands.get("wide_command")
+ if wide_command:
+ net_connect.send_command(wide_command)
+ assert True
+
def test_ssh_connect(net_connect, commands, expected_responses):
"""Verify the connection was established successfully."""
- show_version = net_connect.send_command_expect(commands["version"])
+ show_version = net_connect.send_command(commands["version"])
assert expected_responses["version_banner"] in show_version
+
def test_ssh_connect_cm(net_connect_cm, commands, expected_responses):
"""Test the context manager."""
prompt_str = net_connect_cm
- assert expected_responses['base_prompt'] in prompt_str
+ assert expected_responses["base_prompt"] in prompt_str
+
def test_send_command_timing(net_connect, commands, expected_responses):
"""Verify a command can be sent down the channel successfully."""
time.sleep(1)
net_connect.clear_buffer()
- show_ip = net_connect.send_command_timing(commands["basic"])
- assert expected_responses['interface_ip'] in show_ip
+ # Force verification of command echo
+ show_ip = net_connect.send_command_timing(commands["basic"], cmd_verify=True)
+ assert expected_responses["interface_ip"] in show_ip
+
-def test_send_command_expect(net_connect, commands, expected_responses):
- """Verify a command can be sent down the channel successfully using _expect method."""
+def test_send_command_timing_no_cmd_verify(net_connect, commands, expected_responses):
+ # Skip devices that are performance optimized (i.e. cmd_verify is required there)
+ if net_connect.fast_cli is True:
+ assert pytest.skip()
time.sleep(1)
net_connect.clear_buffer()
- show_ip_alt = net_connect.send_command_expect(commands["basic"])
- assert expected_responses['interface_ip'] in show_ip_alt
+ # cmd_verify=False is the default
+ show_ip = net_connect.send_command_timing(commands["basic"], cmd_verify=False)
+ assert expected_responses["interface_ip"] in show_ip
+
+
+def test_send_command(net_connect, commands, expected_responses):
+ """Verify a command can be sent down the channel successfully using send_command method."""
+ net_connect.clear_buffer()
+ show_ip_alt = net_connect.send_command(commands["basic"])
+ assert expected_responses["interface_ip"] in show_ip_alt
+
+
+def test_send_command_no_cmd_verify(net_connect, commands, expected_responses):
+ # Skip devices that are performance optimized (i.e. cmd_verify is required there)
+ if net_connect.fast_cli is True:
+ assert pytest.skip()
+ net_connect.clear_buffer()
+ show_ip_alt = net_connect.send_command(commands["basic"], cmd_verify=False)
+ assert expected_responses["interface_ip"] in show_ip_alt
+
+
+def test_complete_on_space_disabled(net_connect, commands, expected_responses):
+ """Verify complete on space is disabled."""
+ # If complete on space is enabled will get re-written to "show configuration groups"
+ if net_connect.device_type in ["juniper_junos", "nokia_sros"]:
+ if (
+ net_connect.device_type == "nokia_sros"
+ and "@" not in net_connect.base_prompt
+ ):
+ # Only MD-CLI supports disable of command complete on space
+ assert pytest.skip()
+ cmd = commands.get("abbreviated_cmd")
+ cmd_full = commands.get("abbreviated_cmd_full")
+ net_connect.write_channel(f"{cmd}\n")
+ output = net_connect.read_until_prompt()
+ assert cmd_full not in output
+ else:
+ assert pytest.skip()
+
+
+def test_send_command_textfsm(net_connect, commands, expected_responses):
+ """Verify a command can be sent down the channel successfully using send_command method."""
+
+ base_platform = net_connect.device_type
+ if base_platform.count("_") >= 2:
+ # Strip off the _ssh, _telnet, _serial
+ base_platform = base_platform.split("_")[:-1]
+ base_platform = "_".join(base_platform)
+ if base_platform not in [
+ "cisco_ios",
+ "cisco_xe",
+ "cisco_xr",
+ "cisco_nxos",
+ "arista_eos",
+ "cisco_asa",
+ "juniper_junos",
+ "hp_procurve",
+ ]:
+ assert pytest.skip("TextFSM/ntc-templates not supported on this platform")
+ else:
+ time.sleep(1)
+ net_connect.clear_buffer()
+ fallback_cmd = commands.get("basic")
+ command = commands.get("basic_textfsm", fallback_cmd)
+ show_ip_alt = net_connect.send_command(command, use_textfsm=True)
+ assert isinstance(show_ip_alt, list)
+
+
+def test_send_command_ttp(net_connect):
+ """
+ Verify a command can be sent down the channel
+ successfully using send_command method.
+ """
+
+ base_platform = net_connect.device_type
+ if base_platform.count("_") >= 2:
+ # Strip off the _ssh, _telnet, _serial
+ base_platform = base_platform.split("_")[:-1]
+ base_platform = "_".join(base_platform)
+ if base_platform not in ["cisco_ios"]:
+ assert pytest.skip("TTP template not existing for this platform")
+ else:
+ time.sleep(1)
+ net_connect.clear_buffer()
+
+ # write a simple template to file
+ ttp_raw_template = (
+ "interface {{ intf_name }}\n description {{ description | ORPHRASE}}"
+ )
+
+ with open("show_run_interfaces.ttp", "w") as writer:
+ writer.write(ttp_raw_template)
+
+ command = "show run | s interface"
+ show_ip_alt = net_connect.send_command(
+ command, use_ttp=True, ttp_template="show_run_interfaces.ttp"
+ )
+ assert isinstance(show_ip_alt, list)
+ # Unwrap outer lists
+ show_ip_alt = show_ip_alt[0][0]
+ assert isinstance(show_ip_alt, list)
+ assert isinstance(show_ip_alt[0], dict)
+ assert isinstance(show_ip_alt[0]["intf_name"], str)
+
+
+def test_send_command_genie(net_connect, commands, expected_responses):
+ """Verify a command can be sent down the channel successfully using send_command method."""
+
+ base_platform = net_connect.device_type
+ if base_platform.count("_") >= 2:
+ # Strip off the _ssh, _telnet, _serial
+ base_platform = base_platform.split("_")[:-1]
+ base_platform = "_".join(base_platform)
+ if base_platform not in [
+ "cisco_ios",
+ "cisco_xe",
+ "cisco_xr",
+ "cisco_nxos",
+ "cisco_asa",
+ ]:
+ assert pytest.skip("Genie not supported on this platform")
+ else:
+ time.sleep(1)
+ net_connect.clear_buffer()
+ fallback_cmd = commands.get("basic")
+ 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)
+
+
+def test_send_multiline_timing(net_connect):
+
+ debug = False
+
+ if (
+ "cisco_ios" not in net_connect.device_type
+ and "cisco_xe" not in net_connect.device_type
+ ):
+ assert pytest.skip()
+ count = 100
+ cmd_list = ["ping", "", "8.8.8.8", str(count), "", "", "", ""]
+ output = net_connect.send_multiline_timing(cmd_list)
+ if debug:
+ print(output)
+ assert output.count("!") >= 95
+
+
+def test_send_multiline(net_connect):
+
+ debug = False
+ if (
+ "cisco_ios" not in net_connect.device_type
+ and "cisco_xe" not in net_connect.device_type
+ ):
+ assert pytest.skip()
+ commands = (
+ ("ping", r"ip"),
+ ("", r"Target IP address"),
+ ("8.8.8.8", "Repeat count"),
+ ("100", "Datagram size"),
+ ("", "Timeout in seconds"),
+ ("", "Extended"),
+ ("", "Sweep"),
+ ("", ""),
+ )
+ output = net_connect.send_multiline(commands)
+ if debug:
+ print(output)
+ assert output.count("!") >= 95
+
+
+def test_send_multiline_prompt(net_connect):
+ """Use send_multiline, but use device's prompt as expect_string"""
+
+ debug = False
+ if (
+ "cisco_ios" not in net_connect.device_type
+ and "cisco_xe" not in net_connect.device_type
+ ):
+ assert pytest.skip()
+ commands = (
+ ("show ip int brief", ""),
+ ("show interfaces", ""),
+ ("show version", ""),
+ )
+ output = net_connect.send_multiline(commands)
+ if debug:
+ print(output)
+ assert "is down" in output
+ assert "Configuration register" in output
+
+
+def test_send_multiline_simple(net_connect):
+ """
+ Use send_multiline with commands in a list. Device's prompt will be the
+ expect_string between each command.
+ """
+
+ debug = False
+ if (
+ "cisco_ios" not in net_connect.device_type
+ and "cisco_xe" not in net_connect.device_type
+ ):
+ assert pytest.skip()
+ commands = [
+ "show ip int brief",
+ "show interfaces",
+ "show version",
+ ]
+ output = net_connect.send_multiline(commands)
+ if debug:
+ print(output)
+ assert "is down" in output
+ assert "Configuration register" in output
+
def test_base_prompt(net_connect, commands, expected_responses):
"""Verify the router prompt is detected correctly."""
- assert net_connect.base_prompt == expected_responses['base_prompt']
+ assert net_connect.base_prompt == expected_responses["base_prompt"]
+
def test_strip_prompt(net_connect, commands, expected_responses):
"""Ensure the router prompt is not in the command output."""
+
+ if expected_responses["base_prompt"] == "":
+ return
show_ip = net_connect.send_command_timing(commands["basic"])
- show_ip_alt = net_connect.send_command_expect(commands["basic"])
- assert expected_responses['base_prompt'] not in show_ip
- assert expected_responses['base_prompt'] not in show_ip_alt
+ show_ip_alt = net_connect.send_command(commands["basic"])
+ assert expected_responses["base_prompt"] not in show_ip
+ assert expected_responses["base_prompt"] not in show_ip_alt
+
def test_strip_command(net_connect, commands, expected_responses):
"""Ensure that the command that was executed does not show up in the command output."""
show_ip = net_connect.send_command_timing(commands["basic"])
- show_ip_alt = net_connect.send_command_expect(commands["basic"])
- assert commands['basic'] not in show_ip
- assert commands['basic'] not in show_ip_alt
+ show_ip_alt = net_connect.send_command(commands["basic"])
+
+ # dlink_ds has an echo of the command in the command output
+ if "dlink_ds" in net_connect.device_type:
+ show_ip = "\n".join(show_ip.split("\n")[2:])
+ show_ip_alt = "\n".join(show_ip_alt.split("\n")[2:])
+ assert commands["basic"] not in show_ip
+ assert commands["basic"] not in show_ip_alt
+
def test_normalize_linefeeds(net_connect, commands, expected_responses):
"""Ensure no '\r\n' sequences."""
show_version = net_connect.send_command_timing(commands["version"])
- show_version_alt = net_connect.send_command_expect(commands["version"])
- assert not '\r\n' in show_version
- assert not '\r\n' in show_version_alt
+ show_version_alt = net_connect.send_command(commands["version"])
+ assert "\r\n" not in show_version
+ assert "\r\n" not in show_version_alt
+
def test_clear_buffer(net_connect, commands, expected_responses):
"""Test that clearing the buffer works."""
+
+ # x!@#!# Mikrotik
+ enter = net_connect.RETURN
# Manually send a command down the channel so that data needs read.
- net_connect.write_channel(commands["basic"] + '\n')
- time.sleep(4)
+ net_connect.write_channel(f"{commands['basic']}{enter}")
+ time.sleep(1)
net_connect.clear_buffer()
+ time.sleep(2)
# Should not be anything there on the second pass
clear_buffer_check = net_connect.clear_buffer()
- assert clear_buffer_check is None
+ assert clear_buffer_check == ""
+
def test_enable_mode(net_connect, commands, expected_responses):
- '''
+ """
Test entering enable mode
Catch exception for devices that don't support enable
- '''
+ """
try:
net_connect.enable()
enable_prompt = net_connect.find_prompt()
- assert enable_prompt == expected_responses['enable_prompt']
+ assert enable_prompt == expected_responses["enable_prompt"]
except AttributeError:
- assert True == True
+ assert True
+
def test_disconnect(net_connect, commands, expected_responses):
"""Terminate the SSH session."""
+ start_time = datetime.now()
net_connect.disconnect()
+ end_time = datetime.now()
+ time_delta = end_time - start_time
+ assert net_connect.remote_conn is None
+ assert time_delta.total_seconds() < 8
+
+
+def test_disconnect_no_enable(net_connect_newconn, commands, expected_responses):
+ """Terminate the SSH session from privilege level1"""
+ net_connect = net_connect_newconn
+ if "cisco_ios" in net_connect.device_type:
+ net_connect.send_command_timing("disable")
+ start_time = datetime.now()
+ net_connect.disconnect()
+ end_time = datetime.now()
+ time_delta = end_time - start_time
+ assert net_connect.remote_conn is None
+ assert time_delta.total_seconds() < 5
+ else:
+ assert True
diff --git a/tests/test_netmiko_tcl.py b/tests/test_netmiko_tcl.py
index 2a4a3d4ec..ccb08e961 100755
--- a/tests/test_netmiko_tcl.py
+++ b/tests/test_netmiko_tcl.py
@@ -1,14 +1,4 @@
#!/usr/bin/env python
-from __future__ import print_function
-from __future__ import unicode_literals
-import time
-import sys
-import os
-from datetime import datetime
-from getpass import getpass
-from netmiko import ConnectHandler, InLineTransfer
-
-
def test_tcl_put(tcl_fixture):
ssh_conn, transfer = tcl_fixture
if transfer.check_file_exists():
@@ -17,32 +7,37 @@ def test_tcl_put(tcl_fixture):
transfer._enter_tcl_mode()
transfer.put_file()
transfer._exit_tcl_mode()
- assert transfer.check_file_exists() == True
+ assert transfer.check_file_exists() is True
+
def test_remote_space_available(tcl_fixture):
ssh_conn, transfer = tcl_fixture
remote_space = transfer.remote_space_available()
assert remote_space >= 30000000
-
+
+
def test_verify_space_available_put(tcl_fixture):
ssh_conn, transfer = tcl_fixture
- assert transfer.verify_space_available() == True
+ assert transfer.verify_space_available() is True
# intentional make there not be enough space available
transfer.file_size = 1000000000
- assert transfer.verify_space_available() == False
+ assert transfer.verify_space_available() is False
+
def test_remote_file_size(tcl_fixture):
ssh_conn, transfer = tcl_fixture
remote_file_size = transfer.remote_file_size()
assert remote_file_size == 20
+
def test_md5_methods(tcl_fixture):
ssh_conn, transfer = tcl_fixture
- md5_value = '4313f1adae86a21117441b0a95d482a7'
+ md5_value = "4313f1adae86a21117441b0a95d482a7"
remote_md5 = transfer.remote_md5()
assert remote_md5 == md5_value
- assert transfer.compare_md5() == True
+ assert transfer.compare_md5() is True
+
def test_disconnect(tcl_fixture):
"""Terminate the SSH session."""
diff --git a/tests/test_nxos.sh b/tests/test_nxos.sh
deleted file mode 100755
index f200dca97..000000000
--- a/tests/test_nxos.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-echo "Starting tests...good luck:" \
-&& echo "Cisco NXOS" \
-&& py.test -v test_netmiko_show.py --test_device nxos1 \
-&& py.test -v test_netmiko_config.py --test_device nxos1 \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_out/test_arista_eos.stderr b/tests/test_out/test_arista_eos.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_asa.stderr b/tests/test_out/test_cisco_asa.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_ios.stderr b/tests/test_out/test_cisco_ios.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_nxos.stderr b/tests/test_out/test_cisco_nxos.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_xe.stderr b/tests/test_out/test_cisco_xe.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_xr_azure.stderr b/tests/test_out/test_cisco_xr_azure.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_cisco_xr_xrv.stderr b/tests/test_out/test_cisco_xr_xrv.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_out/test_juniper_junos.stderr b/tests/test_out/test_juniper_junos.stderr
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_s300.sh b/tests/test_s300.sh
deleted file mode 100755
index c5d748534..000000000
--- a/tests/test_s300.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Cisco SG300" \
-&& py.test -v test_netmiko_show.py --test_device cisco_s300 \
-&& py.test -v test_netmiko_config.py --test_device cisco_s300 \
-\
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_scp.sh b/tests/test_scp.sh
deleted file mode 100755
index 0cebead60..000000000
--- a/tests/test_scp.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-echo "Starting tests...good luck:" \
-&& echo "SCP Tests" \
-&& py.test test_netmiko_scp.py::test_file_transfer --test_device cisco881 \
-&& py.test test_netmiko_scp.py::test_file_transfer --test_device nxos1 \
-&& py.test -s -v test_netmiko_scp.py::test_file_transfer --test_device arista_sw4 \
-&& py.test -s -v test_netmiko_scp.py::test_file_transfer --test_device juniper_srx \
-&& py.test -s -v test_netmiko_scp.py::test_file_transfer --test_device cisco_xrv \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_suite_alt.sh b/tests/test_suite_alt.sh
index d81d8ef9d..ba174437d 100755
--- a/tests/test_suite_alt.sh
+++ b/tests/test_suite_alt.sh
@@ -1,80 +1,141 @@
#!/bin/sh
RETURN_CODE=0
+PYTEST='py.test -s -v -x'
# Exit on the first test failure and set RETURN_CODE = 1
echo "Starting tests...good luck:" \
+\
+&& echo "Cisco IOS-XE SSH (including SCP)" \
+&& $PYTEST test_netmiko_scp.py --test_device cisco3 \
+&& $PYTEST test_netmiko_show.py --test_device cisco3 \
+&& $PYTEST test_netmiko_config.py --test_device cisco3 \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco3 \
+\
+&& echo "Exception and Timeout Tests" \
+&& $PYTEST test_netmiko_exceptions.py \
+\
+&& echo "Juniper vMX" \
+&& $PYTEST test_netmiko_show.py --test_device juniper_vmx \
+&& $PYTEST test_netmiko_config.py --test_device juniper_vmx \
+\
+&& echo "Cisco IOS-XR (Azure)" \
+&& $PYTEST test_netmiko_show.py --test_device cisco_xr_azure \
+&& $PYTEST test_netmiko_config.py --test_device cisco_xr_azure \
+&& $PYTEST test_netmiko_commit.py --test_device cisco_xr_azure \
+\
&& echo "Cisco IOS SSH (including SCP) using key auth" \
-&& py.test -v test_netmiko_scp.py --test_device cisco881_key \
-&& py.test -v test_netmiko_tcl.py --test_device cisco881_key \
-&& py.test -v test_netmiko_show.py --test_device cisco881_key \
-&& py.test -v test_netmiko_config.py --test_device cisco881_key \
+&& $PYTEST test_netmiko_tcl.py --test_device cisco881_key \
+&& $PYTEST test_netmiko_show.py --test_device cisco881_key \
+&& $PYTEST test_netmiko_config.py --test_device cisco881_key \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco881_key \
\
&& echo "Cisco IOS SSH (including SCP)" \
-&& py.test -v test_netmiko_scp.py --test_device cisco881 \
-&& py.test -v test_netmiko_tcl.py --test_device cisco881 \
-&& py.test -v test_netmiko_show.py --test_device cisco881 \
-&& py.test -v test_netmiko_config.py --test_device cisco881 \
+&& $PYTEST test_netmiko_tcl.py --test_device cisco1 \
+&& $PYTEST test_netmiko_show.py --test_device cisco1 \
+&& $PYTEST test_netmiko_config.py --test_device cisco1 \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco1 \
+\
+&& echo "Cisco IOS SSH fast_cli (including SCP)" \
+&& $PYTEST test_netmiko_tcl.py --test_device cisco881_fast \
+&& $PYTEST test_netmiko_show.py --test_device cisco881_fast \
+&& $PYTEST test_netmiko_config.py --test_device cisco881_fast \
\
&& echo "Cisco IOS using SSH config with SSH Proxy" \
-&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_config \
-&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_config \
+&& $PYTEST test_netmiko_show.py --test_device cisco881_ssh_config \
+&& $PYTEST test_netmiko_config.py --test_device cisco881_ssh_config \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco881_ssh_config \
+\
+&& echo "Cisco IOS using SSH config with SSH Proxy using ProxyJump" \
+&& $PYTEST test_netmiko_show.py --test_device cisco881_ssh_proxyjump \
+&& $PYTEST test_netmiko_config.py --test_device cisco881_ssh_proxyjump \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco881_ssh_proxyjump \
+\
+&& echo "Cisco IOS session log testing" \
+&& $PYTEST test_netmiko_session_log.py --test_device cisco881_slog \
\
&& echo "Cisco IOS telnet" \
-&& py.test -v test_netmiko_show.py --test_device cisco881_telnet \
-&& py.test -v test_netmiko_config.py --test_device cisco881_telnet \
+&& $PYTEST test_netmiko_show.py --test_device cisco881_telnet \
+&& $PYTEST test_netmiko_config.py --test_device cisco881_telnet \
+&& $PYTEST test_netmiko_config_acl.py --test_device cisco881_telnet \
\
&& echo "Cisco SG300" \
-&& py.test -v test_netmiko_show.py --test_device cisco_s300 \
-&& py.test -v test_netmiko_config.py --test_device cisco_s300 \
+&& $PYTEST test_netmiko_show.py --test_device cisco_s300 \
+&& $PYTEST test_netmiko_config.py --test_device cisco_s300 \
\
&& echo "Arista" \
-&& py.test -v test_netmiko_scp.py --test_device arista_sw4 \
-&& py.test -v test_netmiko_show.py --test_device arista_sw4 \
-&& py.test -v test_netmiko_config.py --test_device arista_sw4 \
-\
-&& echo "HP ProCurve" \
-&& py.test -v test_netmiko_show.py --test_device hp_procurve \
-&& py.test -v test_netmiko_config.py --test_device hp_procurve \
-\
-&& echo "HP Comware7" \
-&& py.test -v test_netmiko_show.py --test_device hp_comware \
-&& py.test -v test_netmiko_config.py --test_device hp_comware \
+&& $PYTEST test_netmiko_scp.py --test_device arista_sw \
+&& $PYTEST test_netmiko_show.py --test_device arista_sw \
+&& $PYTEST test_netmiko_config.py --test_device arista_sw \
+&& $PYTEST test_netmiko_config_acl.py --test_device arista_sw \
\
&& echo "Juniper" \
-&& py.test -v test_netmiko_scp.py --test_device juniper_srx \
-&& py.test -v test_netmiko_show.py --test_device juniper_srx \
-&& py.test -v test_netmiko_config.py --test_device juniper_srx \
-&& py.test -v test_netmiko_commit.py --test_device juniper_srx \
+&& $PYTEST test_netmiko_scp.py --test_device juniper_srx \
+&& $PYTEST test_netmiko_show.py --test_device juniper_srx \
+&& $PYTEST test_netmiko_config.py --test_device juniper_srx \
+&& $PYTEST test_netmiko_commit.py --test_device juniper_srx \
\
&& echo "Cisco ASA" \
-&& py.test -v test_netmiko_show.py --test_device cisco_asa \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa \
-&& py.test -v test_netmiko_show.py --test_device cisco_asa_login \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa_login \
+&& $PYTEST test_netmiko_show.py --test_device cisco_asa \
+&& $PYTEST test_netmiko_config.py --test_device cisco_asa \
+&& $PYTEST test_netmiko_show.py --test_device cisco_asa_login \
+&& $PYTEST test_netmiko_config.py --test_device cisco_asa_login \
\
&& echo "Cisco IOS-XR" \
-&& py.test -v test_netmiko_scp.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_show.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_config.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_commit.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_scp.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_show.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_config.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_commit.py --test_device cisco_xrv \
\
&& echo "Cisco NXOS" \
-&& py.test -v test_netmiko_scp.py --test_device nxos1 \
-&& py.test -v test_netmiko_show.py --test_device nxos1 \
-&& py.test -v test_netmiko_config.py --test_device nxos1 \
+&& $PYTEST test_netmiko_scp.py --test_device nxos1 \
+&& $PYTEST test_netmiko_show.py --test_device nxos1 \
+&& $PYTEST test_netmiko_config.py --test_device nxos1 \
\
&& echo "Linux SSH (using keys)" \
-&& py.test -v test_netmiko_scp.py --test_device linux_srv1 \
-&& py.test -s -v test_netmiko_show.py --test_device linux_srv1 \
+&& $PYTEST test_netmiko_scp.py --test_device linux_srv1 \
+&& $PYTEST test_netmiko_show.py --test_device linux_srv1 \
+\
+&& echo "Test read_timeout on Cisco3 (slow, slow, and more slow)" \
+&& $PYTEST test_timeout_read_until_pattern.py --test_device cisco3 \
+&& $PYTEST test_timeout_send_command.py --test_device cisco3 \
+&& $PYTEST test_timeout_read_timing.py --test_device cisco3 \
+&& $PYTEST test_timeout_send_command_timing.py --test_device cisco3 \
\
&& echo "Autodetect tests" \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco881 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device arista_sw4 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device juniper_srx \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_asa \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_autodetect.py --test_device cisco1 \
+&& $PYTEST test_netmiko_autodetect.py --test_device arista_sw \
+&& $PYTEST test_netmiko_autodetect.py --test_device juniper_srx \
+&& $PYTEST test_netmiko_autodetect.py --test_device cisco_asa \
+&& $PYTEST test_netmiko_autodetect.py --test_device cisco_xrv \
+&& $PYTEST test_netmiko_autodetect.py --test_device cisco_xr_azure \
+\
+&& echo "HP ProCurve" \
+&& $PYTEST test_netmiko_show.py --test_device hp_procurve \
+&& $PYTEST test_netmiko_config.py --test_device hp_procurve \
\
|| RETURN_CODE=1
exit $RETURN_CODE
+
+# && echo "HP Comware7" \
+# && py.test -v test_netmiko_show.py --test_device hp_comware \
+# && py.test -v test_netmiko_config.py --test_device hp_comware \
+# \
+# Can't get Cisco IOS and SCP get to run reliably--IOS bug?
+# && py.test -v test_netmiko_scp.py --test_device cisco881_key \
+# && py.test -v test_netmiko_scp.py --test_device cisco881 \
+# && py.test -v test_netmiko_scp.py --test_device cisco881_fast \
+#
+#
+#&& 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 \
+#\
diff --git a/tests/test_suite_tmp.sh b/tests/test_suite_tmp.sh
deleted file mode 100755
index a283e368c..000000000
--- a/tests/test_suite_tmp.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Cisco IOS SSH (including SCP) using key auth" \
-&& py.test -v test_netmiko_scp.py --test_device cisco881_key \
-&& py.test -v test_netmiko_tcl.py --test_device cisco881_key \
-&& py.test -v test_netmiko_show.py --test_device cisco881_key \
-&& py.test -v test_netmiko_config.py --test_device cisco881_key \
-\
-&& echo "Cisco IOS SSH (including SCP)" \
-&& py.test -v test_netmiko_scp.py --test_device cisco881 \
-&& py.test -v test_netmiko_tcl.py --test_device cisco881 \
-&& py.test -v test_netmiko_show.py --test_device cisco881 \
-&& py.test -v test_netmiko_config.py --test_device cisco881 \
-\
-&& echo "Cisco IOS using SSH config with SSH Proxy" \
-&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_config \
-&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_config \
-\
-&& echo "Cisco IOS telnet" \
-&& py.test -v test_netmiko_show.py --test_device cisco881_telnet \
-&& py.test -v test_netmiko_config.py --test_device cisco881_telnet \
-\
-&& echo "Cisco SG300" \
-&& py.test -v test_netmiko_show.py --test_device cisco_s300 \
-&& py.test -v test_netmiko_config.py --test_device cisco_s300 \
-\
-&& echo "Arista" \
-&& py.test -v test_netmiko_scp.py --test_device arista_sw4 \
-&& py.test -v test_netmiko_show.py --test_device arista_sw4 \
-&& py.test -v test_netmiko_config.py --test_device arista_sw4 \
-\
-&& echo "HP ProCurve" \
-&& py.test -v test_netmiko_show.py --test_device hp_procurve \
-&& py.test -v test_netmiko_config.py --test_device hp_procurve \
-\
-&& echo "Juniper" \
-&& py.test -v test_netmiko_scp.py --test_device juniper_srx \
-&& py.test -v test_netmiko_show.py --test_device juniper_srx \
-&& py.test -v test_netmiko_config.py --test_device juniper_srx \
-&& py.test -v test_netmiko_commit.py --test_device juniper_srx \
-\
-&& echo "Cisco ASA" \
-&& py.test -v test_netmiko_show.py --test_device cisco_asa \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa \
-&& py.test -v test_netmiko_show.py --test_device cisco_asa_login \
-&& py.test -v test_netmiko_config.py --test_device cisco_asa_login \
-\
-&& echo "Cisco IOS-XR" \
-&& py.test -v test_netmiko_scp.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_show.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_config.py --test_device cisco_xrv \
-&& py.test -v test_netmiko_commit.py --test_device cisco_xrv \
-\
-&& echo "Cisco NXOS" \
-&& py.test -v test_netmiko_scp.py --test_device nxos1 \
-&& py.test -v test_netmiko_show.py --test_device nxos1 \
-&& py.test -v test_netmiko_config.py --test_device nxos1 \
-\
-&& echo "Linux SSH (using keys)" \
-&& py.test -s -v test_netmiko_show.py --test_device linux_srv1 \
-\
-&& echo "Autodetect tests" \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco881 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device arista_sw4 \
-&& py.test -s -v test_netmiko_autodetect.py --test_device juniper_srx \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_asa \
-&& py.test -s -v test_netmiko_autodetect.py --test_device cisco_xrv \
-\
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_timeout_read_timing.py b/tests/test_timeout_read_timing.py
new file mode 100644
index 000000000..956fff366
--- /dev/null
+++ b/tests/test_timeout_read_timing.py
@@ -0,0 +1,123 @@
+from datetime import datetime
+
+"""
+DONE Working traceroute
+DONE Failing traceroute
+DONE show tech-support output
+DONE pinging unreachable destination
+DONE pinging 10,000 times to reachable destination
+DONE generating md5/sha hash for a software image
+ failing traceroute that you break out of.
+ Image transfer of very large file.
+ show ip bgp output
+ copying big files on a device
+ doing a ftp/tftp/http copy initiated on the device
+"""
+
+
+def execute_cmd(conn, cmd="show tech-support", read_timeout=None, last_read=2.0):
+ start_time = datetime.now()
+ cmd = cmd.strip()
+ conn.write_channel(cmd + "\n")
+ if read_timeout is None:
+ output = conn.read_channel_timing(last_read=last_read)
+ else:
+ output = conn.read_channel_timing(
+ read_timeout=read_timeout, last_read=last_read
+ )
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ return (output, exec_time)
+
+
+def test_read_show_tech(net_connect_newconn):
+
+ read_timeout = 0
+ output, exec_time = execute_cmd(
+ net_connect_newconn, read_timeout=read_timeout, last_read=4.0
+ )
+
+ assert "show interface" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_md5(net_connect_newconn):
+
+ cmd = "verify /sha512 flash:/c1100-universalk9_ias.16.12.03.SPA.bin\n"
+ # cmd = "verify /md5 flash:/c1100-universalk9_ias.16.12.03.SPA.bin\n"
+ output, exec_time = execute_cmd(net_connect_newconn, cmd=cmd)
+ assert "Done!" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_ping(net_connect_newconn):
+
+ cmd = "ping 8.8.8.8 repeat 10000\n"
+ output, exec_time = execute_cmd(net_connect_newconn, cmd=cmd)
+ assert "Success rate is" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_ping_no_response(net_connect_newconn):
+
+ # Nothing exists at that IP
+ cmd = "ping 10.220.88.209 repeat 20\n"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ )
+ assert "Success rate is" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute_no_response(net_connect_newconn):
+
+ # Will finish in about 90 seconds
+ cmd = "traceroute 8.8.8.8 probe 1"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ # read_timeout=300,
+ )
+ assert "cisco3#" in output
+ assert output.count("*") == 30
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute_no_response_full(net_connect_newconn):
+
+ # Will finish in about 4.5 minutes
+ cmd = "traceroute 8.8.8.8"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ read_timeout=6 * 60, # allow 6-minutes
+ )
+ assert "cisco3#" in output
+ assert output.count("*") == 90
+ assert exec_time.total_seconds() > 100
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute(net_connect_newconn):
+
+ cmd = "traceroute 10.220.88.37"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ )
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 5
+ net_connect_newconn.disconnect()
diff --git a/tests/test_timeout_read_until_pattern.py b/tests/test_timeout_read_until_pattern.py
new file mode 100644
index 000000000..17372ed28
--- /dev/null
+++ b/tests/test_timeout_read_until_pattern.py
@@ -0,0 +1,125 @@
+from datetime import datetime
+import pytest
+import time
+import re
+from netmiko import ReadTimeout
+
+
+def execute_cmd(conn, pattern, read_timeout, cmd="show tech-support\n", max_loops=None):
+ conn.write_channel("show tech-support\n")
+ return conn.read_until_pattern(
+ pattern=pattern, read_timeout=read_timeout, max_loops=max_loops
+ )
+
+
+def my_cleanup(conn, sleep=180):
+ try:
+ # Must be long enough for "show tech-support" to finish
+ time.sleep(sleep)
+ conn.disconnect()
+ except Exception:
+ # If it fails, just try to keep going
+ pass
+
+
+def show_long_running(conn, read_timeout, expect_string):
+ start_time = datetime.now()
+ my_exception = None
+ try:
+ execute_cmd(conn, pattern=expect_string, read_timeout=read_timeout)
+ except Exception as e:
+ my_exception = e
+ finally:
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ # clean-up
+ my_cleanup(conn)
+ return (my_exception, exec_time)
+
+
+def show_long_running_notimeout(conn, read_timeout):
+ """This execution should work i.e. no exception."""
+ start_time = datetime.now()
+
+ my_prompt = conn.find_prompt()
+ pattern = re.escape(my_prompt)
+
+ output = execute_cmd(conn, pattern=pattern, read_timeout=read_timeout)
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ return (output, exec_time)
+
+
+def test_read_longrunning_cmd(net_connect_newconn):
+
+ read_timeout = 300
+ output, exec_time = show_long_running_notimeout(
+ net_connect_newconn, read_timeout=read_timeout
+ )
+ assert "show interface" in output
+ assert exec_time.total_seconds() > 10
+
+
+@pytest.mark.parametrize(
+ "test_timeout,allowed_percentage",
+ [(0.4, 5.0), (1, 2.0), (5, 1.0), (10, 0.5), (60, 0.2)],
+)
+def test_read_timeout(net_connect_newconn, test_timeout, allowed_percentage):
+
+ # Explicitly send expect_string so timing is more accurate
+ my_prompt = net_connect_newconn.find_prompt()
+ pattern = re.escape(my_prompt)
+
+ my_except, exec_time = show_long_running(
+ net_connect_newconn, read_timeout=test_timeout, expect_string=pattern
+ )
+
+ # Returned exception should be read_timeout
+ assert isinstance(my_except, ReadTimeout)
+
+ # Calculate difference in execution time from timeout
+ time_diff = abs(exec_time.total_seconds() - test_timeout)
+ # Convert difference to a percentage of expected timeout
+ time_margin_percent = time_diff / test_timeout * 100
+ # Margin off should be less than the allowed_percentage
+ assert time_margin_percent < allowed_percentage
+
+
+@pytest.mark.parametrize(
+ "test_timeout,allowed_percentage", [(1, 2.0), (5, 1.0), (10, 0.5), (60, 0.2)]
+)
+def test_read_timeout_override(net_connect_newconn, test_timeout, allowed_percentage):
+
+ net_connect_newconn.read_timeout_override = 12
+ ssh_conn = net_connect_newconn
+
+ # Explicitly send expect_string so timing is more accurate
+ my_prompt = net_connect_newconn.find_prompt()
+ pattern = re.escape(my_prompt)
+
+ my_except, exec_time = show_long_running(
+ ssh_conn, read_timeout=test_timeout, expect_string=pattern
+ )
+
+ # Returned exception should be read_timeout
+ assert isinstance(my_except, ReadTimeout)
+
+ # For comparsions compare to the override time with a fixed allowed percentage
+ test_timeout = ssh_conn.read_timeout_override
+ allowed_percentage = 0.5
+
+ # Calculate difference in execution time from read_timeout_override
+ time_diff = abs(exec_time.total_seconds() - test_timeout)
+
+ # Convert difference to a percentage of expected timeout
+ time_margin_percent = time_diff / test_timeout * 100
+ # Margin off should be less than the allowed_percentage
+ assert time_margin_percent < allowed_percentage
+
+
+def test_deprecation_max_loops(net_connect_newconn):
+
+ nc = net_connect_newconn
+ cmd = "show ip int brief"
+ with pytest.deprecated_call():
+ execute_cmd(nc, pattern=r"#", read_timeout=10, cmd=cmd, max_loops=1000)
diff --git a/tests/test_timeout_send_command.py b/tests/test_timeout_send_command.py
new file mode 100644
index 000000000..ee5530c7d
--- /dev/null
+++ b/tests/test_timeout_send_command.py
@@ -0,0 +1,182 @@
+from datetime import datetime
+import pytest
+import time
+import re
+from netmiko import ReadTimeout
+
+# Setting to True will slow things down (as will wait until "show tech-support" completes.
+CLEANUP = True
+
+
+def my_cleanup(conn, sleep=180):
+ try:
+ # Must be long enough for "show tech-support" to finish
+ time.sleep(sleep)
+ conn.disconnect()
+ except Exception:
+ # If it fails, just try to keep going
+ pass
+
+
+def show_long_running(
+ conn, read_timeout, expect_string, delay_factor=None, max_loops=None
+):
+ start_time = datetime.now()
+ my_exception = None
+ try:
+ conn.send_command(
+ "show tech-support",
+ read_timeout=read_timeout,
+ expect_string=expect_string,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+ except Exception as e:
+ my_exception = e
+ finally:
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ # clean-up
+ if CLEANUP:
+ my_cleanup(conn)
+ return (my_exception, exec_time)
+
+
+def show_long_running_notimeout(conn, read_timeout):
+ start_time = datetime.now()
+ output = conn.send_command("show tech-support", read_timeout=read_timeout)
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ return (output, exec_time)
+
+
+def test_read_longrunning_cmd(net_connect_newconn):
+
+ read_timeout = 300
+ output, exec_time = show_long_running_notimeout(
+ net_connect_newconn, read_timeout=read_timeout
+ )
+ assert "show interface" in output
+ assert exec_time.total_seconds() > 10
+
+
+@pytest.mark.parametrize(
+ "test_timeout,allowed_percentage",
+ [(0.4, 5.0), (1, 2.0), (5, 1.0), (10, 0.5), (60, 0.2)],
+)
+def test_read_timeout(net_connect_newconn, test_timeout, allowed_percentage):
+
+ # Explicitly send expect_string so timing is more accurate
+ my_prompt = net_connect_newconn.find_prompt()
+ pattern = re.escape(my_prompt)
+
+ my_except, exec_time = show_long_running(
+ net_connect_newconn, read_timeout=test_timeout, expect_string=pattern
+ )
+
+ # Returned exception should be read_timeout
+ assert isinstance(my_except, ReadTimeout)
+
+ # Calculate difference in execution time from timeout
+ time_diff = abs(exec_time.total_seconds() - test_timeout)
+ # Convert difference to a percentage of expected timeout
+ time_margin_percent = time_diff / test_timeout * 100
+ # Margin off should be less than the allowed_percentage
+ assert time_margin_percent < allowed_percentage
+
+
+@pytest.mark.parametrize(
+ "test_timeout,allowed_percentage", [(1, 2.0), (5, 1.0), (10, 0.5), (60, 0.2)]
+)
+def test_read_timeout_override(net_connect_newconn, test_timeout, allowed_percentage):
+
+ net_connect_newconn.read_timeout_override = 12
+ ssh_conn = net_connect_newconn
+
+ # Explicitly send expect_string so timing is more accurate
+ my_prompt = net_connect_newconn.find_prompt()
+ pattern = re.escape(my_prompt)
+
+ my_except, exec_time = show_long_running(
+ ssh_conn, read_timeout=test_timeout, expect_string=pattern
+ )
+
+ # Returned exception should be read_timeout
+ assert isinstance(my_except, ReadTimeout)
+
+ # For comparsions compare to the override time with a fixed allowed percentage
+ test_timeout = ssh_conn.read_timeout_override
+ allowed_percentage = 0.5
+
+ # Calculate difference in execution time from read_timeout_override
+ time_diff = abs(exec_time.total_seconds() - test_timeout)
+
+ # Convert difference to a percentage of expected timeout
+ time_margin_percent = time_diff / test_timeout * 100
+ # Margin off should be less than the allowed_percentage
+ assert time_margin_percent < allowed_percentage
+
+
+def test_deprecation_delay_factor(net_connect_newconn):
+
+ ssh_conn = net_connect_newconn
+ cmd = "show ip int brief"
+ with pytest.deprecated_call():
+ ssh_conn.send_command(cmd, delay_factor=2)
+
+
+def test_deprecation_max_loops(net_connect_newconn):
+
+ ssh_conn = net_connect_newconn
+ cmd = "show ip int brief"
+ with pytest.deprecated_call():
+ ssh_conn.send_command(cmd, max_loops=1000)
+
+
+@pytest.mark.parametrize(
+ "fast_cli,delay_factor,max_loops,compat_timeout",
+ [
+ (True, None, None, 10),
+ (False, 1.0, 100, 20),
+ (False, 2.0, 100, 40),
+ (False, 5.0, 40, 40),
+ ],
+)
+def test_netmiko3_compatibility_mode(
+ net_connect_newconn, fast_cli, delay_factor, max_loops, compat_timeout
+):
+ """
+ In this test read_timeout is ignored and the timeout used by
+ send_command should be calculated from global_delay_factor/delay_factor/max_loops
+ """
+
+ nc = net_connect_newconn
+ # Force it into Netmiko 3.x compatibility mode
+ nc.delay_factor_compat = True
+
+ allowed_percentage = 0.5
+ if not fast_cli:
+ nc.fast_cli = False
+ nc.global_delay_factor = 1.0
+
+ # Explicitly send expect_string so timing is more accurate
+ my_prompt = nc.find_prompt()
+ pattern = re.escape(my_prompt)
+ my_except, exec_time = show_long_running(
+ nc,
+ read_timeout=20,
+ expect_string=pattern,
+ delay_factor=delay_factor,
+ max_loops=max_loops,
+ )
+ print(exec_time)
+
+ # Returned exception should be read_timeout
+ assert isinstance(my_except, ReadTimeout)
+
+ # Calculate difference in execution time from timeout
+ time_diff = abs(exec_time.total_seconds() - compat_timeout)
+ # Convert difference to a percentage of expected timeout
+ time_margin_percent = time_diff / compat_timeout * 100
+ # Margin off should be less than the allowed_percentage
+ assert time_margin_percent < allowed_percentage
diff --git a/tests/test_timeout_send_command_timing.py b/tests/test_timeout_send_command_timing.py
new file mode 100644
index 000000000..134a0ee09
--- /dev/null
+++ b/tests/test_timeout_send_command_timing.py
@@ -0,0 +1,106 @@
+from datetime import datetime
+
+
+def execute_cmd(conn, cmd="show tech-support", read_timeout=None, last_read=2.0):
+ start_time = datetime.now()
+ if read_timeout is None:
+ output = conn.send_command_timing(cmd, last_read=last_read, strip_prompt=False)
+ else:
+ output = conn.send_command_timing(
+ cmd, read_timeout=read_timeout, last_read=last_read, strip_prompt=False
+ )
+ end_time = datetime.now()
+ exec_time = end_time - start_time
+ return (output, exec_time)
+
+
+def test_read_show_tech(net_connect_newconn):
+
+ read_timeout = 0
+ output, exec_time = execute_cmd(
+ net_connect_newconn, read_timeout=read_timeout, last_read=4.0
+ )
+ assert "show interface" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_md5(net_connect_newconn):
+
+ cmd = "verify /sha512 flash:/c1100-universalk9_ias.16.12.03.SPA.bin\n"
+ # cmd = "verify /md5 flash:/c1100-universalk9_ias.16.12.03.SPA.bin\n"
+ output, exec_time = execute_cmd(net_connect_newconn, cmd=cmd)
+ assert "Done!" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_ping(net_connect_newconn):
+
+ cmd = "ping 8.8.8.8 repeat 10000\n"
+ output, exec_time = execute_cmd(net_connect_newconn, cmd=cmd)
+ assert "Success rate is" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_ping_no_response(net_connect_newconn):
+
+ # Nothing exists at that IP
+ cmd = "ping 10.220.88.209 repeat 20\n"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ )
+ assert "Success rate is" in output
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute_no_response(net_connect_newconn):
+
+ # Will finish in about 90 seconds
+ cmd = "traceroute 8.8.8.8 probe 1"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ # read_timeout=300,
+ )
+ assert "cisco3#" in output
+ assert output.count("*") == 30
+ assert exec_time.total_seconds() > 10
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute_no_response_full(net_connect_newconn):
+
+ # Will finish in about 4.5 minutes
+ cmd = "traceroute 8.8.8.8"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ read_timeout=6 * 60, # allow 6-minutes
+ )
+ assert "cisco3#" in output
+ assert output.count("*") == 90
+ assert exec_time.total_seconds() > 100
+ net_connect_newconn.disconnect()
+
+
+def test_read_traceroute(net_connect_newconn):
+
+ cmd = "traceroute 10.220.88.37"
+ output, exec_time = execute_cmd(
+ net_connect_newconn,
+ cmd=cmd,
+ last_read=4.0,
+ )
+ assert "cisco3#" in output
+ assert exec_time.total_seconds() > 5
+ net_connect_newconn.disconnect()
diff --git a/tests/test_ubiquiti_edgeswitch.sh b/tests/test_ubiquiti_edgeswitch.sh
deleted file mode 100755
index b87ef055a..000000000
--- a/tests/test_ubiquiti_edgeswitch.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-RETURN_CODE=0
-
-# Exit on the first test failure and set RETURN_CODE = 1
-echo "Starting tests...good luck:" \
-&& echo "Ubiquiti EdgeSwitch" \
-&& py.test -v test_netmiko_show.py --test_device ubiquiti_edgeswitch \
-&& py.test -v test_netmiko_config.py --test_device ubiquiti_edgeswitch \
-|| RETURN_CODE=1
-
-exit $RETURN_CODE
diff --git a/tests/test_utils.py b/tests/test_utils.py
index acf3d2802..719a96cf2 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -2,12 +2,10 @@
"""
Implement common functions for tests
"""
-from __future__ import print_function
-from __future__ import unicode_literals
-
import io
import sys
+
def parse_yaml(yaml_file):
"""
Parses a yaml file, returning its contents as a dict.
@@ -19,7 +17,7 @@ def parse_yaml(yaml_file):
sys.exit("Unable to import yaml module.")
try:
- with io.open(yaml_file, encoding='utf-8') as fname:
- return yaml.load(fname)
+ with io.open(yaml_file, encoding="utf-8") as fname:
+ return yaml.safe_load(fname)
except IOError:
sys.exit("Unable to open YAML file: {0}".format(yaml_file))
diff --git a/tests/unit/.netmiko.yml b/tests/unit/.netmiko.yml
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/unit/test_base_connection.py b/tests/unit/test_base_connection.py
new file mode 100755
index 000000000..350586402
--- /dev/null
+++ b/tests/unit/test_base_connection.py
@@ -0,0 +1,482 @@
+#!/usr/bin/env python
+
+import time
+from os.path import dirname, join
+from threading import Lock
+
+from netmiko import NetmikoTimeoutException
+from netmiko.base_connection import BaseConnection
+
+RESOURCE_FOLDER = join(dirname(dirname(__file__)), "etc")
+
+
+class FakeBaseConnection(BaseConnection):
+ def __init__(self, **kwargs):
+ for key, value in kwargs.items():
+ setattr(self, key, value)
+ self._session_locker = Lock()
+
+
+def test_timeout_exceeded():
+ """Raise NetmikoTimeoutException if waiting too much"""
+ connection = FakeBaseConnection(session_timeout=10)
+ start = time.time() - 11
+ try:
+ connection._timeout_exceeded(start)
+ except NetmikoTimeoutException as exc:
+ assert isinstance(exc, NetmikoTimeoutException)
+ return
+
+ assert False
+
+
+def test_timeout_not_exceeded():
+ """Do not raise NetmikoTimeoutException if not waiting too much"""
+ connection = FakeBaseConnection(session_timeout=10)
+ start = time.time()
+ assert not connection._timeout_exceeded(start)
+
+
+def test_timeout_invalid_start():
+ """Test invalid timeout start value"""
+ connection = FakeBaseConnection(session_timeout=10)
+ assert not connection._timeout_exceeded(start=0)
+
+
+def test_use_ssh_file():
+ """Update SSH connection parameters based on the SSH "config" file"""
+ connection = FakeBaseConnection(
+ host="localhost",
+ port=22,
+ username="",
+ password="secret",
+ use_keys=True,
+ allow_agent=False,
+ key_file="/home/user/.ssh/id_rsa",
+ timeout=60,
+ pkey=None,
+ passphrase=None,
+ disabled_algorithms=None,
+ auth_timeout=None,
+ banner_timeout=10,
+ conn_timeout=5,
+ ssh_config_file=join(RESOURCE_FOLDER, "ssh_config"),
+ sock=None,
+ )
+
+ connect_dict = connection._connect_params_dict()
+
+ expected = {
+ "hostname": "10.10.10.70",
+ "port": 8022,
+ "username": "admin",
+ "password": "secret",
+ "look_for_keys": True,
+ "allow_agent": False,
+ "key_filename": "/home/user/.ssh/id_rsa",
+ "timeout": 5,
+ "pkey": None,
+ "passphrase": None,
+ "disabled_algorithms": None,
+ "auth_timeout": None,
+ "banner_timeout": 10,
+ }
+
+ result = connection._use_ssh_config(connect_dict)
+ assert "sock" in result
+ assert len(result["sock"].cmd) == 5
+ assert "nc" in result["sock"].cmd
+ del result["sock"]
+ assert result == expected
+
+
+def test_use_ssh_file_proxyjump():
+ """Update SSH connection parameters based on the SSH "config" file"""
+ connection = FakeBaseConnection(
+ host="10.10.10.70",
+ port=22,
+ username="",
+ password="secret",
+ use_keys=True,
+ allow_agent=False,
+ key_file="/home/user/.ssh/id_rsa",
+ timeout=60,
+ pkey=None,
+ passphrase=None,
+ disabled_algorithms=None,
+ auth_timeout=None,
+ conn_timeout=5,
+ banner_timeout=10,
+ ssh_config_file=join(RESOURCE_FOLDER, "ssh_config_proxyjump"),
+ sock=None,
+ )
+
+ connect_dict = connection._connect_params_dict()
+
+ expected = {
+ "hostname": "10.10.10.70",
+ "port": 8022,
+ "username": "admin",
+ "password": "secret",
+ "look_for_keys": True,
+ "allow_agent": False,
+ "key_filename": "/home/user/.ssh/id_rsa",
+ "timeout": 5,
+ "pkey": None,
+ "passphrase": None,
+ "disabled_algorithms": None,
+ "auth_timeout": None,
+ "banner_timeout": 10,
+ }
+
+ result = connection._use_ssh_config(connect_dict)
+ assert "sock" in result
+ assert "-W" in result["sock"].cmd
+ del result["sock"]
+ assert result == expected
+
+
+def test_connect_params_dict():
+ """Generate dictionary of Paramiko connection parameters"""
+ connection = FakeBaseConnection(
+ host="localhost",
+ port=22,
+ username="user",
+ password="secret",
+ use_keys=True,
+ allow_agent=False,
+ key_file="/home/user/.ssh/id_rsa",
+ timeout=60,
+ pkey=None,
+ passphrase=None,
+ disabled_algorithms=None,
+ auth_timeout=None,
+ banner_timeout=10,
+ conn_timeout=3,
+ ssh_config_file=None,
+ sock=None,
+ )
+
+ expected = {
+ "hostname": "localhost",
+ "port": 22,
+ "username": "user",
+ "password": "secret",
+ "look_for_keys": True,
+ "allow_agent": False,
+ "key_filename": "/home/user/.ssh/id_rsa",
+ "timeout": 3,
+ "pkey": None,
+ "passphrase": None,
+ "disabled_algorithms": None,
+ "auth_timeout": None,
+ "banner_timeout": 10,
+ "sock": None,
+ }
+ result = connection._connect_params_dict()
+ assert result == expected
+
+
+def test_sanitize_nothing():
+ """Keep command echo, trailing router prompt and ANSI escape codes"""
+
+ output = """
+show cdp neighbors
+Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
+ S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone,
+ D - Remote, C - CVTA, M - Two-port Mac Relay
+
+Device ID Local Intrfce Holdtme Capability Platform Port ID
+
+Total cdp entries displayed : 0
+cisco3#"""
+
+ connection = FakeBaseConnection(
+ RESPONSE_RETURN="\n",
+ RETURN="\n",
+ ansi_escape_codes=False,
+ base_prompt="cisco3#",
+ )
+
+ result = connection._sanitize_output(
+ output,
+ strip_command=False,
+ command_string="show cdp neighbors\n",
+ strip_prompt=False,
+ )
+ assert result == output
+
+
+def test_sanitize_output():
+ """Strip out command echo, trailing router prompt and ANSI escape codes"""
+
+ output = """
+show cdp neighbors
+Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
+ S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone,
+ D - Remote, C - CVTA, M - Two-port Mac Relay
+
+Device ID Local Intrfce Holdtme Capability Platform Port ID
+
+Total cdp entries displayed : 0
+cisco3#"""
+ output = output.lstrip()
+
+ expected = """
+Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
+ S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone,
+ D - Remote, C - CVTA, M - Two-port Mac Relay
+
+Device ID Local Intrfce Holdtme Capability Platform Port ID
+
+Total cdp entries displayed : 0"""
+ expected = expected.lstrip()
+
+ connection = FakeBaseConnection(
+ RESPONSE_RETURN="\n",
+ RETURN="\n",
+ ansi_escape_codes=False,
+ base_prompt="cisco3#",
+ )
+
+ result = connection._sanitize_output(
+ output,
+ strip_command=True,
+ command_string="show cdp neighbors\n",
+ strip_prompt=True,
+ )
+ assert result == expected
+
+
+def test_select_global_delay_factor():
+ """Select the global delay factor"""
+ connection = FakeBaseConnection(global_delay_factor=4, fast_cli=False)
+ assert connection.select_delay_factor(2) == 4
+
+
+def test_select_current_delay_factor():
+ """Select the current delay factor"""
+ connection = FakeBaseConnection(global_delay_factor=4, fast_cli=False)
+ assert connection.select_delay_factor(10) == 10
+
+
+def test_strip_prompt():
+ """Strip the trailing router prompt from the output"""
+ string = """MyRouter version 1.25.9
+myhostname>"""
+ connection = FakeBaseConnection(RESPONSE_RETURN="\n", base_prompt="myhostname>")
+ result = connection.strip_prompt(string)
+ assert result == "MyRouter version 1.25.9"
+
+
+def test_strip_no_prompt():
+ """Strip no prompt from the output"""
+ string = """MyRouter version 1.25.9
+additional text"""
+ connection = FakeBaseConnection(RESPONSE_RETURN="\n", base_prompt="myhostname>")
+ result = connection.strip_prompt(string)
+ assert result == string
+
+
+def test_strip_no_backspaces():
+ """Strip no backspace characters out of the output"""
+ text = "Writing something"
+ output = BaseConnection.strip_backspaces(text)
+ assert output == "Writing something"
+
+
+def test_strip_one_backspaces():
+ """Strip one backspace character out of the output"""
+ text = "Writing\x08something"
+ output = BaseConnection.strip_backspaces(text)
+ assert output == "Writingsomething"
+
+
+def test_strip_backspaces():
+ """Strip any backspace characters out of the output"""
+ text = "Writing\x08something\x08"
+ output = BaseConnection.strip_backspaces(text)
+ assert output == "Writingsomething"
+
+
+def test_strip_command():
+ """Strip command string from output"""
+
+ output = """show cdp neighbors
+Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
+ S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone,
+ D - Remote, C - CVTA, M - Two-port Mac Relay
+
+Device ID Local Intrfce Holdtme Capability Platform Port ID
+
+Total cdp entries displayed : 0
+cisco3#"""
+
+ command = "show cdp neighbors\n"
+ expect = """
+Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
+ S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone,
+ D - Remote, C - CVTA, M - Two-port Mac Relay
+
+Device ID Local Intrfce Holdtme Capability Platform Port ID
+
+Total cdp entries displayed : 0
+cisco3#"""
+ expect = expect.lstrip()
+
+ connection = FakeBaseConnection(RESPONSE_RETURN="\n")
+ result = connection.strip_command(command, output)
+ assert result == expect
+
+
+def test_strip_command_w_backspaces():
+ """Strip command string from output and remove backspaces"""
+ output = """echo "hello world"
+hello \x08world
+myhost\x08name>
+"""
+ command = 'echo "hello world"'
+ expect = """hello world
+myhostname>
+"""
+ connection = FakeBaseConnection(RESPONSE_RETURN="\n")
+ result = connection.strip_command(command, output)
+ assert result == expect
+
+
+def test_normalize_linefeeds():
+ """Convert combinations of carriage returns and newlines to standardized form."""
+ text = """show hostname\r
+show version\r\r
+show inventory\r\r\r
+show interfaces
+\r"""
+ expected = """show hostname
+show version
+show inventory
+show interfaces
+"""
+ connection = FakeBaseConnection(RESPONSE_RETURN="\n")
+ result = connection.normalize_linefeeds(text)
+ assert result == expected
+
+
+def test_normalize_cmd():
+ """Normalize CLI commands to have a single trailing newline"""
+ connection = FakeBaseConnection(RETURN="\n")
+ result = connection.normalize_cmd("show version \n\n\n ")
+ assert result == "show version\n"
+
+
+def test_unlocking_no_lock():
+ """Try unlocking when the lock is already released"""
+ connection = FakeBaseConnection()
+ assert not connection._session_locker.locked()
+ connection._unlock_netmiko_session()
+ assert not connection._session_locker.locked()
+
+
+def test_locking_unlocking():
+ """Try to lock and unlock"""
+ connection = FakeBaseConnection()
+ assert not connection._session_locker.locked()
+ connection._lock_netmiko_session()
+ assert connection._session_locker.locked()
+ connection._unlock_netmiko_session()
+ assert not connection._session_locker.locked()
+
+
+def lock_unlock_timeout(timeout=0):
+ """Try to lock when it is already locked"""
+ connection = FakeBaseConnection(session_timeout=timeout)
+ assert not connection._session_locker.locked()
+ connection._lock_netmiko_session()
+ assert connection._session_locker.locked()
+
+ try:
+ connection._lock_netmiko_session()
+ except NetmikoTimeoutException:
+ return
+ finally:
+ assert connection._session_locker.locked()
+ connection._unlock_netmiko_session()
+ assert not connection._session_locker.locked()
+
+ assert False
+
+
+def test_lock_timeout():
+ """Try to lock when it is already locked"""
+ lock_unlock_timeout(0)
+
+
+def test_lock_timeout_loop():
+ """Try to lock when it is already locked, wait 100ms"""
+ lock_unlock_timeout(0.2)
+
+
+def test_strip_ansi_codes():
+ connection = FakeBaseConnection(RETURN="\n")
+ ansi_codes_to_strip = [
+ "\x1b[30m", # Black
+ "\x1b[31m", # Red
+ "\x1b[32m", # Green
+ "\x1b[33m", # Yellow
+ "\x1b[34m", # Blue
+ "\x1b[35m", # Magenta
+ "\x1b[36m", # Cyan
+ "\x1b[37m", # White
+ "\x1b[39m", # Default(foreground color at startup)
+ "\x1b[90m", # Light Gray
+ "\x1b[91m", # Light Red
+ "\x1b[92m", # Light Green
+ "\x1b[93m", # Light Yellow
+ "\x1b[94m", # Light Blue
+ "\x1b[95m", # Light Magenta
+ "\x1b[96m", # Light Cyan
+ "\x1b[97m", # Light White
+ "\x1b[40m", # Black
+ "\x1b[41m", # Red
+ "\x1b[42m", # Green
+ "\x1b[43m", # Yellow
+ "\x1b[44m", # Blue
+ "\x1b[45m", # Magenta
+ "\x1b[46m", # Cyan
+ "\x1b[47m", # White
+ "\x1b[49m", # Default(background color at startup)
+ "\x1b[100m", # Light Gray
+ "\x1b[101m", # Light Red
+ "\x1b[102m", # Light Green
+ "\x1b[103m", # Light Yellow
+ "\x1b[104m", # Light Blue
+ "\x1b[105m", # Light Magenta
+ "\x1b[106m", # Light Cyan
+ "\x1b[107m", # Light White
+ "\x1b[1;5H", # code_position_cursor r"\[\d+;\d+H"
+ "\x1b[?25h", # code_show_cursor
+ "\x1b[K", # code_erase_line_end
+ "\x1b[2K", # code_erase_line
+ "\x1b[K", # code_erase_start_line
+ "\x1b[1;2r", # code_enable_scroll
+ "\x1b[1M", # code_carriage_return
+ "\x1b[?7l", # code_disable_line_wrapping
+ "\x1b[?7l", # code_reset_mode_screen_options
+ "\x1b[00m", # code_reset_graphics_mode
+ "\x1b[J", # code_erase_display
+ "\x1b[6n", # code_get_cursor_position
+ "\x1b[m", # code_cursor_position
+ "\x1b[J", # code_erase_display
+ "\x1b[0m", # code_attrs_off
+ "\x1b[7m", # code_reverse
+ ]
+ for ansi_code in ansi_codes_to_strip:
+ assert connection.strip_ansi_escape_codes(ansi_code) == ""
+
+ # code_insert_line must be substituted with n-returns
+ ansi_insert_line = "\x1b[1L"
+ assert connection.strip_ansi_escape_codes(ansi_insert_line) == "\n"
+ ansi_insert_line = "\x1b[3L"
+ assert connection.strip_ansi_escape_codes(ansi_insert_line) == "\n\n\n"
+
+ # code_next_line must be substituted with a return
+ assert connection.strip_ansi_escape_codes("\x1bE") == "\n"
diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py
new file mode 100755
index 000000000..303bfec85
--- /dev/null
+++ b/tests/unit/test_connection.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+import pytest
+import logging
+from netmiko import ConnectHandler, ConnLogOnly, ConnUnify
+from netmiko import NetmikoAuthenticationException
+from netmiko import NetmikoTimeoutException
+from netmiko import ConnectionException
+
+
+# Fictional devices that will fail
+DEVICE1 = {
+ "host": "localhost",
+ "device_type": "linux",
+ "username": "bogus",
+ "password": "bogus",
+}
+
+DEVICE2 = {
+ "host": "localhost",
+ "device_type": "linux",
+ "username": "bogus",
+ "password": "bogus",
+ "port": 8022,
+}
+
+
+def test_connecthandler():
+ with pytest.raises(NetmikoAuthenticationException):
+ net_connect = ConnectHandler(**DEVICE1)
+ with pytest.raises(NetmikoTimeoutException):
+ net_connect = ConnectHandler(**DEVICE2) # noqa
+
+
+def test_connlogonly(caplog):
+ log_level = logging.INFO
+ log_file = "my_output.log"
+
+ net_connect = ConnLogOnly(log_file=log_file, log_level=log_level, **DEVICE1)
+ assert net_connect is None
+ net_connect = ConnLogOnly(log_file=log_file, log_level=log_level, **DEVICE2)
+ assert net_connect is None
+
+ assert "ERROR" in caplog.text
+ assert caplog.text.count("ERROR") == 2
+ assert "Authentication failure" in caplog.text
+ assert "was unable to reach the provided host and port" in caplog.text
+
+
+def test_connunify():
+ with pytest.raises(ConnectionException):
+ net_connect = ConnUnify(**DEVICE1)
+ with pytest.raises(ConnectionException):
+ net_connect = ConnUnify(**DEVICE2) # noqa
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"
diff --git a/tests/unit/test_utilities.py b/tests/unit/test_utilities.py
new file mode 100755
index 000000000..4355dabd2
--- /dev/null
+++ b/tests/unit/test_utilities.py
@@ -0,0 +1,396 @@
+#!/usr/bin/env python
+
+import os
+import sys
+from os.path import dirname, join, relpath
+import pytest
+
+from netmiko import utilities
+from textfsm import clitable
+
+RESOURCE_FOLDER = join(dirname(dirname(__file__)), "etc")
+RELATIVE_RESOURCE_FOLDER = join(dirname(dirname(relpath(__file__))), "etc")
+CONFIG_FILENAME = join(RESOURCE_FOLDER, ".netmiko.yml")
+
+
+def test_load_yaml_file():
+ """Read a YAML file successfully"""
+ filename = join(RESOURCE_FOLDER, "yaml_test.yml")
+ expected = {
+ "answer": 42,
+ "hello": "world",
+ "complex": {"truth": False, "key": "value"},
+ }
+ assert utilities.load_yaml_file(filename) == expected
+
+
+def test_invalid_yaml_file():
+ """Try to read an invalid YAML file"""
+ filename = join(RESOURCE_FOLDER, "this_should_not_exist.yml")
+ try:
+ utilities.load_yaml_file(filename)
+ except SystemExit as exc:
+ assert isinstance(exc, SystemExit)
+ return
+ assert False
+
+
+def test_find_cfg_file():
+ """
+ Search for netmiko_tools config file in the following order:
+
+ NETMIKO_TOOLS_CFG environment variable
+ Current directory
+ Home directory
+
+ Look for file named: .netmiko.yml or netmiko.yml
+ """
+ # Search using environment variable (point directly at end file)
+ os.environ["NETMIKO_TOOLS_CFG"] = join(RESOURCE_FOLDER, ".netmiko.yml")
+ assert utilities.find_cfg_file() == CONFIG_FILENAME
+
+ # Search using environment variable (pointing at directory)
+ os.environ["NETMIKO_TOOLS_CFG"] = RESOURCE_FOLDER
+ assert utilities.find_cfg_file() == CONFIG_FILENAME
+
+ try:
+ cwd = os.getcwd()
+ os.chdir(dirname(__file__))
+
+ # Environment var should be preferred over current dir
+ assert utilities.find_cfg_file() == CONFIG_FILENAME
+
+ # Delete env var and verify current dir is returned
+ del os.environ["NETMIKO_TOOLS_CFG"]
+ assert utilities.find_cfg_file() == "./.netmiko.yml"
+ finally:
+ # Change directory back to previous state
+ os.chdir(cwd)
+
+ # Verify explicit call using full filename
+ assert utilities.find_cfg_file(CONFIG_FILENAME) == CONFIG_FILENAME
+
+
+def test_load_cfg_file():
+ """Try to load a configuration file"""
+ expected = {
+ "rtr1": {
+ "device_type": "cisco_ios",
+ "ip": "10.10.10.1",
+ "username": "admin",
+ "password": "cisco123",
+ "secret": "cisco123",
+ },
+ "rtr2": {
+ "device_type": "cisco_ios",
+ "ip": "10.10.10.2",
+ "username": "admin",
+ "password": "cisco123",
+ "secret": "cisco123",
+ },
+ "cisco": ["rtr1", "rtr2"],
+ }
+ assert utilities.load_devices(CONFIG_FILENAME) == expected
+
+
+def test_obtain_all_devices():
+ """Dynamically create 'all' group."""
+ netmiko_tools_load = utilities.load_devices(CONFIG_FILENAME)
+ expected = {
+ "rtr1": {
+ "device_type": "cisco_ios",
+ "ip": "10.10.10.1",
+ "username": "admin",
+ "password": "cisco123",
+ "secret": "cisco123",
+ },
+ "rtr2": {
+ "device_type": "cisco_ios",
+ "ip": "10.10.10.2",
+ "username": "admin",
+ "password": "cisco123",
+ "secret": "cisco123",
+ },
+ }
+ result = utilities.obtain_all_devices(netmiko_tools_load)
+ assert result == expected
+
+
+def test_find_netmiko_dir():
+ """Try to get the netmiko_dir"""
+ folder = dirname(__file__)
+ os.environ["NETMIKO_DIR"] = folder
+ result = utilities.find_netmiko_dir()
+ assert result[0] == folder
+ assert result[1].endswith("/tmp")
+
+
+def test_invalid_netmiko_dir():
+ """Try with an invalid netmiko_base_dir"""
+ os.environ["NETMIKO_DIR"] = "/"
+ try:
+ utilities.find_netmiko_dir()
+ except ValueError as exc:
+ assert isinstance(exc, ValueError)
+ return
+ assert False
+
+
+def test_string_to_bytes():
+ """Convert string to bytes"""
+ assert utilities.write_bytes("test") == b"test"
+
+
+def test_bytes_to_bytes():
+ """Convert bytes to bytes"""
+ result = b"hello world"
+ assert utilities.write_bytes(result) == result
+
+
+def test_invalid_data_to_bytes():
+ """Convert an invalid data type to bytes"""
+ try:
+ utilities.write_bytes(456_779)
+ except ValueError as exc:
+ assert isinstance(exc, ValueError)
+ return
+
+ assert False
+
+
+def test_ensure_resource_dir_exists():
+ """Ensure that the resource folder exists"""
+ utilities.ensure_dir_exists(RESOURCE_FOLDER)
+
+
+def test_ensure_file_exists():
+ """Ensure that a file makes ensure_dir_exists raise an error"""
+ try:
+ utilities.ensure_dir_exists(__file__)
+ except ValueError as exc:
+ assert isinstance(exc, ValueError)
+ return
+ assert False
+
+
+def test_clitable_to_dict():
+ """Converts TextFSM cli_table object to list of dictionaries"""
+ table = clitable.CliTable(template_dir=RESOURCE_FOLDER)
+ text_filename = join(RESOURCE_FOLDER, "textfsm.txt")
+ template_filename = join(RESOURCE_FOLDER, "cisco_ios_show_version.template")
+ with open(text_filename) as data_file:
+ text = data_file.read()
+
+ with open(template_filename) as template_file:
+ table = table._ParseCmdItem(text, template_file)
+
+ result = utilities.clitable_to_dict(table)
+ assert result == [{"model": "4500"}]
+
+
+def test_textfsm_w_index():
+ """Convert raw CLI output to structured data using TextFSM template"""
+ os.environ["NET_TEXTFSM"] = RESOURCE_FOLDER
+ raw_output = "Cisco IOS Software, Catalyst 4500 L3 Switch Software"
+ result = utilities.get_structured_data(
+ raw_output, platform="cisco_ios", command="show version"
+ )
+ assert result == [{"model": "4500"}]
+ result = utilities.get_structured_data_textfsm(
+ raw_output, platform="cisco_ios", command="show version"
+ )
+ assert result == [{"model": "4500"}]
+
+
+def test_ntc_templates_discovery():
+ """
+ Verify Netmiko uses proper ntc-templates:
+
+ Order of preference is:
+ 1. Find directory in `NET_TEXTFSM` Environment Variable.
+ 2. Check for pip installed `ntc-templates` location in this environment.
+ 3. ~/ntc-templates/templates.
+
+ If `index` file is not found in any of these locations, raise ValueError
+ """
+
+ # Check environment variable first
+ os.environ["NET_TEXTFSM"] = RELATIVE_RESOURCE_FOLDER
+ ntc_path = utilities.get_template_dir()
+ assert ntc_path == RESOURCE_FOLDER
+
+ # Next should be PIP installed ntc-tempaltes
+ del os.environ["NET_TEXTFSM"]
+ ntc_path = utilities.get_template_dir()
+ for py_path in sys.path:
+ if "site-packages" in py_path:
+ packages_dir = py_path
+ break
+ assert ntc_path == f"{packages_dir}/ntc_templates/templates"
+
+ # Next should use local index file in ~
+ home_dir = os.path.expanduser("~")
+ # Will not work for CI-CD without pain so just test locally
+ if "kbyers" in home_dir:
+ ntc_path = utilities.get_template_dir(_skip_ntc_package=True)
+ assert ntc_path == f"{home_dir}/ntc-templates/ntc_templates/templates"
+ else:
+ with pytest.raises(ValueError):
+ ntc_path = utilities.get_template_dir(_skip_ntc_package=True)
+
+
+def test_textfsm_index_relative_path():
+ """Test relative path for textfsm ntc directory"""
+ os.environ["NET_TEXTFSM"] = RELATIVE_RESOURCE_FOLDER
+ raw_output = "Cisco IOS Software, Catalyst 4500 L3 Switch Software"
+ result = utilities.get_structured_data_textfsm(
+ raw_output, platform="cisco_ios", command="show version"
+ )
+ assert result == [{"model": "4500"}]
+
+
+def test_textfsm_direct_template():
+ """Convert raw CLI output to structured data using TextFSM template (no index)."""
+ raw_output = "Cisco IOS Software, Catalyst 4500 L3 Switch Software"
+ result = utilities.get_structured_data_textfsm(
+ raw_output,
+ platform="cisco_ios",
+ command="show version",
+ template=f"{RESOURCE_FOLDER}/cisco_ios_show_version.template",
+ )
+ assert result == [{"model": "4500"}]
+
+ # Should also work with no-platform or command
+ result = utilities.get_structured_data_textfsm(
+ raw_output, template=f"{RESOURCE_FOLDER}/cisco_ios_show_version.template"
+ )
+ assert result == [{"model": "4500"}]
+
+
+def test_textfsm_failed_parsing():
+ """Verify raw_output is returned if TextFSM template parsing fails."""
+ raw_output = "This is not 'show version' output"
+ result = utilities.get_structured_data_textfsm(
+ raw_output,
+ platform="cisco_ios",
+ command="show version",
+ template=f"{RESOURCE_FOLDER}/nothinghere",
+ )
+ assert result == raw_output
+
+
+def test_textfsm_missing_template():
+ """Verify raw_output is returned if TextFSM template is missing."""
+ raw_output = "Cisco IOS Software, Catalyst 4500 L3 Switch Software"
+ result = utilities.get_structured_data_textfsm(
+ raw_output,
+ platform="cisco_ios",
+ command="show version",
+ template=f"{RESOURCE_FOLDER}/nothinghere",
+ )
+ assert result == raw_output
+
+
+@pytest.mark.skip(reason="pyats/genie lacks PY3.10 support")
+def test_get_structured_data_genie():
+ """Convert raw CLI output to structured data using Genie"""
+
+ header_line = (
+ "Cisco IOS Software, C3560CX Software (C3560CX-UNIVERSALK9-M), "
+ "Version 15.2(4)E7, RELEASE SOFTWARE (fc2)"
+ )
+ raw_output = """
+Technical Support: http://www.cisco.com/techsupport
+Copyright (c) 1986-2018 by Cisco Systems, Inc.
+Compiled Tue 18-Sep-18 13:20 by prod_rel_team
+
+ROM: Bootstrap program is C3560CX boot loader
+BOOTLDR: C3560CX Boot Loader (C3560CX-HBOOT-M) Version 15.2(4r)E5, RELEASE SOFTWARE (fc4)
+
+3560CX uptime is 5 weeks, 1 day, 2 hours, 30 minutes
+System returned to ROM by power-on
+System restarted at 11:45:26 PDT Tue May 7 2019
+System image file is "flash:c3560cx-universalk9-mz.152-4.E7.bin"
+Last reload reason: power-on
+
+
+
+This product contains cryptographic features and is subject to United
+States and local country laws governing import, export, transfer and
+use. Delivery of Cisco cryptographic products does not imply
+third-party authority to import, export, distribute or use encryption.
+Importers, exporters, distributors and users are responsible for
+compliance with U.S. and local country laws. By using this product you
+agree to comply with applicable laws and regulations. If you are unable
+to comply with U.S. and local laws, return this product immediately.
+
+A summary of U.S. laws governing Cisco cryptographic products may be found at:
+http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
+
+If you require further assistance please contact us by sending email to
+export@cisco.com.
+
+License Level: ipservices
+License Type: Permanent Right-To-Use
+Next reload license Level: ipservices
+
+cisco WS-C3560CX-8PC-S (APM86XXX) processor (revision A0) with 524288K bytes of memory.
+Processor board ID FOCXXXXXXXX
+Last reset from power-on
+5 Virtual Ethernet interfaces
+12 Gigabit Ethernet interfaces
+The password-recovery mechanism is enabled.
+
+512K bytes of flash-simulated non-volatile configuration memory.
+Base ethernet MAC Address : 12:34:56:78:9A:BC
+Motherboard assembly number : 86-75309-01
+Power supply part number : 867-5309-01
+Motherboard serial number : FOCXXXXXXXX
+Power supply serial number : FOCXXXXXXXX
+Model revision number : A0
+Motherboard revision number : A0
+Model number : WS-C3560CX-8PC-S
+System serial number : FOCXXXXXXXX
+Top Assembly Part Number : 86-7530-91
+Top Assembly Revision Number : A0
+Version ID : V01
+CLEI Code Number : CMM1400DRA
+Hardware Board Revision Number : 0x02
+
+
+Switch Ports Model SW Version SW Image
+------ ----- ----- ---------- ----------
+* 1 12 WS-C3560CX-8PC-S 15.2(4)E7 C3560CX-UNIVERSALK9-M
+
+
+Configuration register is 0xF
+"""
+ raw_output = header_line + raw_output
+ result = utilities.get_structured_data_genie(
+ raw_output, platform="cisco_xe", command="show version"
+ )
+ assert result["version"]["chassis"] == "WS-C3560CX-8PC-S"
+
+
+@pytest.mark.parametrize(
+ "max_loops,delay_factor,timeout,result",
+ [
+ (500, 1.0, 100, 100.0), # Defaults, should be 100 seconds
+ (500, 1.0, 90, 90.0), # Defaults except NAPALM overrode timeout
+ (500, 0.1, 100, 10.0), # Defaults, fast_cli should be 10 seconds
+ (500, 5, 100, 500.0), # delay_factor=5 (5x the total sleep)
+ (1500, 5, 100, 1500.0), # delay_factor=5, max_loops=1500 (15x the total sleep)
+ (500, 2, 100, 200.0), # delay_factor=2
+ (500, 10, 100, 1000.0), # delay_factor=10
+ ],
+)
+def test_delay_factor_compat(max_loops, delay_factor, timeout, result):
+
+ read_timeout = utilities.calc_old_timeout(
+ max_loops=max_loops,
+ delay_factor=delay_factor,
+ loop_delay=0.2,
+ old_timeout=timeout,
+ )
+ print(read_timeout)
+ assert read_timeout == result
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index c7d5c005b..000000000
--- a/tox.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[tox]
-envlist = py27,py35,py36
-
-[testenv]
-deps =
- -rrequirements-dev.txt
-
-commands=
- py.test -v -s tests/test_import_netmiko.py
diff --git a/travis_ci_process.txt b/travis_ci_process.txt
deleted file mode 100644
index 16eaafa63..000000000
--- a/travis_ci_process.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-$ tar -cvpf travis_test_env.tar tests/etc/*.yml
-tests/etc/commands.yml
-tests/etc/responses.yml
-tests/etc/test_devices.yml
-
-$ tar -tvpf travis_test_env.tar
--rw-rw-r-- kbyers/kbyers 1776 2015-05-03 18:34 tests/etc/commands.yml
--rw-rw-r-- kbyers/kbyers 1423 2015-05-03 18:35 tests/etc/responses.yml
--rw-rw-r-- kbyers/kbyers 635 2015-05-15 11:01 tests/etc/test_devices.yml
-
-$ travis login
-We need your GitHub login to identify you.
-This information will not be sent to Travis CI, only to api.github.com.
-The password will not be displayed.
-
-Try running with --github-token or --auto if you don't want to enter your password anyway.
-
-$ mv travis_test_env.tar.enc travis_test_env.tar.enc_old
-$ travis encrypt-file travis_test_env.tar
-encrypting travis_test_env.tar for ktbyers/netmiko
-storing result as travis_test_env.tar.enc
-storing secure env variables for decryption
-
-Please add the following to your build script (before_install stage in your .travis.yml, for instance):
-
-
diff --git a/travis_test.py b/travis_test.py
deleted file mode 100644
index 5541688d4..000000000
--- a/travis_test.py
+++ /dev/null
@@ -1,56 +0,0 @@
-'''
-Delay the Travis CI testing for Python versions so that they don't interfere with each other
-'''
-
-from __future__ import print_function
-
-import re
-import os
-import time
-import sys
-
-TRAVIS_DELAY = 0
-
-
-def main():
- '''
- Delay the Travis CI testing for Python versions so that they don't interfere with each other
- '''
- python_version = "{0}.{1}".format(sys.version_info[0], sys.version_info[1])
-
- if re.search(r"^3.5", python_version):
- total_delay = 0 * TRAVIS_DELAY
- print("Python 3.5 found")
- print("Sleeping for {0} seconds".format(total_delay))
- time.sleep(total_delay)
- elif re.search(r"^3.4", python_version):
- total_delay = 1 * TRAVIS_DELAY
- print("Python 3.4 found")
- print("Sleeping for {0} seconds".format(total_delay))
- time.sleep(total_delay)
- elif re.search(r"^3.3", python_version):
- total_delay = 2 * TRAVIS_DELAY
- print("Python 3.3 found")
- print("Sleeping for {0} seconds".format(total_delay))
- time.sleep(total_delay)
- elif re.search(r"^2.7", python_version):
- total_delay = 3 * TRAVIS_DELAY
- print("Python 2.7 found")
- print("Sleeping for {0} seconds".format(total_delay))
- time.sleep(total_delay)
- elif re.search(r"^2.6", python_version):
- total_delay = 4 * TRAVIS_DELAY
- print("Python 2.6 found")
- print("Sleeping for {0} seconds".format(total_delay))
-
- # Execute the unit tests
- return_code = os.system("sh travis_test.sh")
- # return_code comes back as 256 on failure and sys.exit is only 8-bit
- if return_code != 0:
- sys.exit(1)
- else:
- sys.exit(0)
-
-
-if __name__ == "__main__":
- main()
diff --git a/travis_test.sh b/travis_test.sh
deleted file mode 100755
index 973f45e71..000000000
--- a/travis_test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# Execute the unit tests in Travis CI
-RETURN_CODE=0
-cd tests
-./test_suite.sh
-if [ $? -ne 0 ]; then
- RETURN_CODE=1
-fi
-
-exit $RETURN_CODE
diff --git a/travis_test_env.tar.enc b/travis_test_env.tar.enc
deleted file mode 100644
index 46272c344..000000000
Binary files a/travis_test_env.tar.enc and /dev/null differ