一、华为 S5735 配置自动化:背景与挑战
1.1 传统配置方式的痛点
在传统网络管理中,工程师需要逐台登录设备进行配置,这种方式存在诸多痛点。手动配置不仅效率低下,而且容易出错,特别是在大规模网络环境中。当需要批量修改配置时,传统方式需要重复操作,耗时耗力。
#publish-mermaid-0-1793190838794{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-0-1793190838794 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-0-1793190838794 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-0-1793190838794 .error-icon{fill:#552222;}#publish-mermaid-0-1793190838794 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-0-1793190838794 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-0-1793190838794 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-0-1793190838794 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-0-1793190838794 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-0-1793190838794 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-0-1793190838794 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-0-1793190838794 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-0-1793190838794 .marker.cross{stroke:#333333;}#publish-mermaid-0-1793190838794 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-0-1793190838794 p{margin:0;}#publish-mermaid-0-1793190838794 .pieCircle{stroke:black;stroke-width:2px;opacity:0.7;}#publish-mermaid-0-1793190838794 .pieCircle.highlighted{scale:1.05;opacity:1;}#publish-mermaid-0-1793190838794 .pieCircle.highlightedOnHover:hover{transition-duration:250ms;scale:1.05;opacity:1;}#publish-mermaid-0-1793190838794 .pieOuterCircle{stroke:black;stroke-width:2px;fill:none;}#publish-mermaid-0-1793190838794 .pieTitleText{text-anchor:middle;font-size:25px;fill:black;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#publish-mermaid-0-1793190838794 .slice{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;fill:#333;font-size:17px;}#publish-mermaid-0-1793190838794 .legend text{fill:black;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:17px;}#publish-mermaid-0-1793190838794 .node .neo-node{stroke:#9370DB;}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node rect,#publish-mermaid-0-1793190838794 [data-look=\”neo\”].cluster rect,#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-0-1793190838794 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-0-1793190838794 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}35%30%25%10%传统配置方式痛点分布效率低下易出错耗时耗力难以批量操作
该图表显示了传统配置方式的主要痛点分布,其中效率低下和易出错是最主要的问题。
1.2 自动化配置的必要性
随着网络规模不断扩大,自动化配置成为必然趋势。自动化配置可以确保配置的一致性,减少人为错误,提高配置效率。对于华为 S5735 系列交换机,通过 Python 脚本实现配置自动化,可以显著提升网络管理效率。
#publish-mermaid-1-1793190838822{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-1-1793190838822 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-1-1793190838822 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-1-1793190838822 .error-icon{fill:#552222;}#publish-mermaid-1-1793190838822 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-1-1793190838822 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-1-1793190838822 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-1-1793190838822 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-1-1793190838822 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-1-1793190838822 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-1-1793190838822 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-1-1793190838822 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-1-1793190838822 .marker.cross{stroke:#333333;}#publish-mermaid-1-1793190838822 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-1-1793190838822 p{margin:0;}#publish-mermaid-1-1793190838822 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-1-1793190838822 .cluster-label text{fill:#333;}#publish-mermaid-1-1793190838822 .cluster-label span{color:#333;}#publish-mermaid-1-1793190838822 .cluster-label span p{background-color:transparent;}#publish-mermaid-1-1793190838822 .label text,#publish-mermaid-1-1793190838822 span{fill:#333;color:#333;}#publish-mermaid-1-1793190838822 .node rect,#publish-mermaid-1-1793190838822 .node circle,#publish-mermaid-1-1793190838822 .node ellipse,#publish-mermaid-1-1793190838822 .node polygon,#publish-mermaid-1-1793190838822 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1-1793190838822 .rough-node .label text,#publish-mermaid-1-1793190838822 .node .label text,#publish-mermaid-1-1793190838822 .image-shape .label,#publish-mermaid-1-1793190838822 .icon-shape .label{text-anchor:middle;}#publish-mermaid-1-1793190838822 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-1-1793190838822 .rough-node .label,#publish-mermaid-1-1793190838822 .node .label,#publish-mermaid-1-1793190838822 .image-shape .label,#publish-mermaid-1-1793190838822 .icon-shape .label{text-align:center;}#publish-mermaid-1-1793190838822 .node.clickable{cursor:pointer;}#publish-mermaid-1-1793190838822 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-1-1793190838822 .arrowheadPath{fill:#333333;}#publish-mermaid-1-1793190838822 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-1-1793190838822 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-1-1793190838822 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1-1793190838822 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-1-1793190838822 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1-1793190838822 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-1-1793190838822 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-1-1793190838822 .cluster text{fill:#333;}#publish-mermaid-1-1793190838822 .cluster span{color:#333;}#publish-mermaid-1-1793190838822 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-1-1793190838822 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-1-1793190838822 rect.text{fill:none;stroke-width:0;}#publish-mermaid-1-1793190838822 .icon-shape,#publish-mermaid-1-1793190838822 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-1-1793190838822 .icon-shape p,#publish-mermaid-1-1793190838822 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-1-1793190838822 .icon-shape .label rect,#publish-mermaid-1-1793190838822 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-1-1793190838822 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-1-1793190838822 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-1-1793190838822 .node .neo-node{stroke:#9370DB;}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node rect,#publish-mermaid-1-1793190838822 [data-look=\”neo\”].cluster rect,#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1-1793190838822 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-1-1793190838822 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
手动配置
效率低
易出错
难以批量操作
自动化配置
提高效率
减少错误
确保一致性
该流程图展示了从手动配置到自动化配置的转换过程及其带来的好处。
二、Python Paramiko:实现配置自动化的核心工具
2.1 Paramiko 库简介
Paramiko 是一个用于 SSHv2 协议的 Python 实现,提供了客户端和服务器功能。它支持 SSH 连接、SFTP 文件传输等功能,是网络自动化中常用的工具之一。
#publish-mermaid-2-1793190839045{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-2-1793190839045 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-2-1793190839045 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-2-1793190839045 .error-icon{fill:#552222;}#publish-mermaid-2-1793190839045 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-2-1793190839045 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-2-1793190839045 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-2-1793190839045 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-2-1793190839045 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-2-1793190839045 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-2-1793190839045 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-2-1793190839045 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-2-1793190839045 .marker.cross{stroke:#333333;}#publish-mermaid-2-1793190839045 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-2-1793190839045 p{margin:0;}#publish-mermaid-2-1793190839045 g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#publish-mermaid-2-1793190839045 g.classGroup text .title{font-weight:bolder;}#publish-mermaid-2-1793190839045 .cluster-label text{fill:#333;}#publish-mermaid-2-1793190839045 .cluster-label span{color:#333;}#publish-mermaid-2-1793190839045 .cluster-label span p{background-color:transparent;}#publish-mermaid-2-1793190839045 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-2-1793190839045 .cluster text{fill:#333;}#publish-mermaid-2-1793190839045 .cluster span{color:#333;}#publish-mermaid-2-1793190839045 .nodeLabel,#publish-mermaid-2-1793190839045 .edgeLabel{color:#131300;}#publish-mermaid-2-1793190839045 .noteLabel .nodeLabel,#publish-mermaid-2-1793190839045 .noteLabel .edgeLabel{color:black;}#publish-mermaid-2-1793190839045 .edgeLabel .label rect{fill:#ECECFF;}#publish-mermaid-2-1793190839045 .label text{fill:#131300;}#publish-mermaid-2-1793190839045 .labelBkg{background:#ECECFF;}#publish-mermaid-2-1793190839045 .edgeLabel .label span{background:#ECECFF;}#publish-mermaid-2-1793190839045 .classTitle{font-weight:bolder;}#publish-mermaid-2-1793190839045 .node rect,#publish-mermaid-2-1793190839045 .node circle,#publish-mermaid-2-1793190839045 .node ellipse,#publish-mermaid-2-1793190839045 .node polygon,#publish-mermaid-2-1793190839045 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1;}#publish-mermaid-2-1793190839045 .divider{stroke:#9370DB;stroke-width:1;}#publish-mermaid-2-1793190839045 g.clickable{cursor:pointer;}#publish-mermaid-2-1793190839045 g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#publish-mermaid-2-1793190839045 g.classGroup line{stroke:#9370DB;stroke-width:1;}#publish-mermaid-2-1793190839045 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#publish-mermaid-2-1793190839045 .classLabel .label{fill:#9370DB;font-size:10px;}#publish-mermaid-2-1793190839045 .relation{stroke:#333333;stroke-width:1;fill:none;}#publish-mermaid-2-1793190839045 .dashed-line{stroke-dasharray:3;}#publish-mermaid-2-1793190839045 .dotted-line{stroke-dasharray:1 2;}#publish-mermaid-2-1793190839045 [id$=\”-compositionStart\”],#publish-mermaid-2-1793190839045 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-compositionEnd\”],#publish-mermaid-2-1793190839045 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-dependencyStart\”],#publish-mermaid-2-1793190839045 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-dependencyEnd\”],#publish-mermaid-2-1793190839045 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-extensionStart\”],#publish-mermaid-2-1793190839045 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-extensionEnd\”],#publish-mermaid-2-1793190839045 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-aggregationStart\”],#publish-mermaid-2-1793190839045 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-aggregationEnd\”],#publish-mermaid-2-1793190839045 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-lollipopStart\”],#publish-mermaid-2-1793190839045 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 [id$=\”-lollipopEnd\”],#publish-mermaid-2-1793190839045 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-2-1793190839045 .edgeTerminals{font-size:11px;line-height:initial;}#publish-mermaid-2-1793190839045 .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-2-1793190839045 .edgeLabel[data-look=\”neo\”]{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-2-1793190839045 .edgeLabel[data-look=\”neo\”] p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-2-1793190839045 .edgeLabel[data-look=\”neo\”] rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-2-1793190839045 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-2-1793190839045 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-2-1793190839045 .node .neo-node{stroke:#9370DB;}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node rect,#publish-mermaid-2-1793190839045 [data-look=\”neo\”].cluster rect,#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-2-1793190839045 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-2-1793190839045 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Paramiko
+SSHClient()
+SFTPClient()
+SSHServer()
+connect(hostname, port, username, password)
+exec_command(command)
+send_file(local_path, remote_path)
该类图展示了 Paramiko 库的主要组件和功能。
2.2 SSH 连接原理
SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络中安全地运行网络服务。Paramiko 通过 SSH 协议与设备建立安全连接,然后执行命令。
交换机客户端交换机客户端#publish-mermaid-3-1793190839122{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-3-1793190839122 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-3-1793190839122 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-3-1793190839122 .error-icon{fill:#552222;}#publish-mermaid-3-1793190839122 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-3-1793190839122 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-3-1793190839122 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-3-1793190839122 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-3-1793190839122 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-3-1793190839122 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-3-1793190839122 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-3-1793190839122 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-3-1793190839122 .marker.cross{stroke:#333333;}#publish-mermaid-3-1793190839122 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-3-1793190839122 p{margin:0;}#publish-mermaid-3-1793190839122 .actor{stroke:#9370DB;fill:#ECECFF;stroke-width:1;}#publish-mermaid-3-1793190839122 rect.actor.outer-path[data-look=\”neo\”]{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 rect.note[data-look=\”neo\”]{stroke:#aaaa33;fill:#fff5ad;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 text.actor>tspan{fill:black;stroke:none;}#publish-mermaid-3-1793190839122 .actor-line{stroke:#9370DB;}#publish-mermaid-3-1793190839122 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#publish-mermaid-3-1793190839122 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#publish-mermaid-3-1793190839122 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#publish-mermaid-3-1793190839122 [id$=\”-arrowhead\”] path{fill:#333;stroke:#333;}#publish-mermaid-3-1793190839122 .sequenceNumber{fill:white;}#publish-mermaid-3-1793190839122 [id$=\”-sequencenumber\”]{fill:#333;}#publish-mermaid-3-1793190839122 [id$=\”-crosshead\”] path{fill:#333;stroke:#333;}#publish-mermaid-3-1793190839122 .messageText{fill:#333;stroke:none;}#publish-mermaid-3-1793190839122 .labelBox{stroke:#9370DB;fill:#ECECFF;filter:none;}#publish-mermaid-3-1793190839122 .labelText,#publish-mermaid-3-1793190839122 .labelText>tspan{fill:black;stroke:none;}#publish-mermaid-3-1793190839122 .loopText,#publish-mermaid-3-1793190839122 .loopText>tspan{fill:black;stroke:none;}#publish-mermaid-3-1793190839122 .sectionTitle,#publish-mermaid-3-1793190839122 .sectionTitle>tspan{fill:black;stroke:none;}#publish-mermaid-3-1793190839122 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:#9370DB;fill:#9370DB;}#publish-mermaid-3-1793190839122 .note{stroke:#aaaa33;fill:#fff5ad;}#publish-mermaid-3-1793190839122 .noteText,#publish-mermaid-3-1793190839122 .noteText>tspan{fill:black;stroke:none;font-weight:normal;}#publish-mermaid-3-1793190839122 .activation0{fill:#f4f4f4;stroke:#666;}#publish-mermaid-3-1793190839122 .activation1{fill:#f4f4f4;stroke:#666;}#publish-mermaid-3-1793190839122 .activation2{fill:#f4f4f4;stroke:#666;}#publish-mermaid-3-1793190839122 .actorPopupMenu{position:absolute;}#publish-mermaid-3-1793190839122 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#publish-mermaid-3-1793190839122 .actor-man circle,#publish-mermaid-3-1793190839122 line{fill:#ECECFF;stroke-width:2px;}#publish-mermaid-3-1793190839122 g rect.rect{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));stroke:#9370DB;}#publish-mermaid-3-1793190839122 .node .neo-node{stroke:#9370DB;}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node rect,#publish-mermaid-3-1793190839122 [data-look=\”neo\”].cluster rect,#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-3-1793190839122 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}发起 SSH 连接返回 SSH 版本信息发送认证信息验证认证信息发送命令返回命令执行结果
该时序图展示了 SSH 连接的基本流程。
三、环境准备与前置条件
3.1 硬件与软件环境
要实现华为 S5735 配置自动化,需要以下环境:
- 华为 S5735 交换机(支持 SSH)
- Python 3.6+
- Paramiko 库
- 网络连接
#publish-mermaid-4-1793190839177{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-4-1793190839177 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-4-1793190839177 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-4-1793190839177 .error-icon{fill:#552222;}#publish-mermaid-4-1793190839177 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-4-1793190839177 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-4-1793190839177 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-4-1793190839177 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-4-1793190839177 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-4-1793190839177 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-4-1793190839177 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-4-1793190839177 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-4-1793190839177 .marker.cross{stroke:#333333;}#publish-mermaid-4-1793190839177 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-4-1793190839177 p{margin:0;}#publish-mermaid-4-1793190839177 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-4-1793190839177 .cluster-label text{fill:#333;}#publish-mermaid-4-1793190839177 .cluster-label span{color:#333;}#publish-mermaid-4-1793190839177 .cluster-label span p{background-color:transparent;}#publish-mermaid-4-1793190839177 .label text,#publish-mermaid-4-1793190839177 span{fill:#333;color:#333;}#publish-mermaid-4-1793190839177 .node rect,#publish-mermaid-4-1793190839177 .node circle,#publish-mermaid-4-1793190839177 .node ellipse,#publish-mermaid-4-1793190839177 .node polygon,#publish-mermaid-4-1793190839177 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-4-1793190839177 .rough-node .label text,#publish-mermaid-4-1793190839177 .node .label text,#publish-mermaid-4-1793190839177 .image-shape .label,#publish-mermaid-4-1793190839177 .icon-shape .label{text-anchor:middle;}#publish-mermaid-4-1793190839177 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-4-1793190839177 .rough-node .label,#publish-mermaid-4-1793190839177 .node .label,#publish-mermaid-4-1793190839177 .image-shape .label,#publish-mermaid-4-1793190839177 .icon-shape .label{text-align:center;}#publish-mermaid-4-1793190839177 .node.clickable{cursor:pointer;}#publish-mermaid-4-1793190839177 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-4-1793190839177 .arrowheadPath{fill:#333333;}#publish-mermaid-4-1793190839177 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-4-1793190839177 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-4-1793190839177 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-4-1793190839177 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-4-1793190839177 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-4-1793190839177 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-4-1793190839177 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-4-1793190839177 .cluster text{fill:#333;}#publish-mermaid-4-1793190839177 .cluster span{color:#333;}#publish-mermaid-4-1793190839177 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-4-1793190839177 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-4-1793190839177 rect.text{fill:none;stroke-width:0;}#publish-mermaid-4-1793190839177 .icon-shape,#publish-mermaid-4-1793190839177 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-4-1793190839177 .icon-shape p,#publish-mermaid-4-1793190839177 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-4-1793190839177 .icon-shape .label rect,#publish-mermaid-4-1793190839177 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-4-1793190839177 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-4-1793190839177 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-4-1793190839177 .node .neo-node{stroke:#9370DB;}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node rect,#publish-mermaid-4-1793190839177 [data-look=\”neo\”].cluster rect,#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-4-1793190839177 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-4-1793190839177 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
硬件环境
华为 S5735 交换机
网络连接
软件环境
Python 3.6+
Paramiko 库
前置条件
SSH 启用
设备可达
该流程图展示了所需的环境和前置条件。
3.2 Python 环境配置
首先需要安装 Python 和 Paramiko 库。可以通过 pip 安装 Paramiko:
pip install paramiko
四、核心代码实现:批量下发命令
4.1 基础连接函数
以下是实现 SSH 连接的基础函数:
import paramiko
def ssh_connect(hostname, username, password, port=22):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, port, username, password)
return ssh
4.2 批量命令下发逻辑
实现批量下发命令的函数:
def batch_execute_commands(ssh, commands):
results = []
for command in commands:
stdin, stdout, stderr = ssh.exec_command(command)
output = stdout.read().decode('utf-8')
error = stderr.read().decode('utf-8')
results.append((command, output, error))
return results
4.3 错误处理与日志记录
添加错误处理和日志记录功能:
import logging
logging.basicConfig(level=logging.INFO)
def safe_execute_commands(ssh, commands):
results = []
for command in commands:
try:
stdin, stdout, stderr = ssh.exec_command(command)
output = stdout.read().decode('utf-8')
error = stderr.read().decode('utf-8')
if error:
logging.error(f"Command failed: {command}\\nError: {error}")
results.append((command, output, error))
except Exception as e:
logging.error(f"Execution error: {e}")
return results
#publish-mermaid-5-1793190839352{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-5-1793190839352 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-5-1793190839352 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-5-1793190839352 .error-icon{fill:#552222;}#publish-mermaid-5-1793190839352 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-5-1793190839352 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-5-1793190839352 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-5-1793190839352 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-5-1793190839352 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-5-1793190839352 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-5-1793190839352 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-5-1793190839352 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-5-1793190839352 .marker.cross{stroke:#333333;}#publish-mermaid-5-1793190839352 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-5-1793190839352 p{margin:0;}#publish-mermaid-5-1793190839352 defs [id$=\”-barbEnd\”]{fill:#333333;stroke:#333333;}#publish-mermaid-5-1793190839352 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#publish-mermaid-5-1793190839352 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#publish-mermaid-5-1793190839352 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#publish-mermaid-5-1793190839352 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#publish-mermaid-5-1793190839352 g.stateGroup line{stroke:#333333;stroke-width:1;}#publish-mermaid-5-1793190839352 .transition{stroke:#333333;stroke-width:1;fill:none;}#publish-mermaid-5-1793190839352 .stateGroup .composit{fill:white;border-bottom:1px;}#publish-mermaid-5-1793190839352 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#publish-mermaid-5-1793190839352 .state-note{stroke:#aaaa33;fill:#fff5ad;}#publish-mermaid-5-1793190839352 .state-note text{fill:black;stroke:none;font-size:10px;}#publish-mermaid-5-1793190839352 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#publish-mermaid-5-1793190839352 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#publish-mermaid-5-1793190839352 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-5-1793190839352 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-5-1793190839352 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-5-1793190839352 .edgeLabel .label text{fill:#333;}#publish-mermaid-5-1793190839352 .label div .edgeLabel{color:#333;}#publish-mermaid-5-1793190839352 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#publish-mermaid-5-1793190839352 .node circle.state-start{fill:#333333;stroke:#333333;}#publish-mermaid-5-1793190839352 .node .fork-join{fill:#333333;stroke:#333333;}#publish-mermaid-5-1793190839352 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#publish-mermaid-5-1793190839352 .end-state-inner{fill:white;stroke-width:1.5;}#publish-mermaid-5-1793190839352 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-5-1793190839352 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-5-1793190839352 [id$=\”-barbEnd\”]{fill:#333333;}#publish-mermaid-5-1793190839352 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-5-1793190839352 .cluster-label,#publish-mermaid-5-1793190839352 .nodeLabel{color:#131300;}#publish-mermaid-5-1793190839352 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#publish-mermaid-5-1793190839352 .statediagram-state .divider{stroke:#9370DB;}#publish-mermaid-5-1793190839352 .statediagram-state .title-state{rx:5px;ry:5px;}#publish-mermaid-5-1793190839352 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#publish-mermaid-5-1793190839352 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#publish-mermaid-5-1793190839352 .statediagram-cluster .inner{rx:0;ry:0;}#publish-mermaid-5-1793190839352 .statediagram-state rect.basic{rx:5px;ry:5px;}#publish-mermaid-5-1793190839352 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#publish-mermaid-5-1793190839352 .note-edge{stroke-dasharray:5;}#publish-mermaid-5-1793190839352 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#publish-mermaid-5-1793190839352 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#publish-mermaid-5-1793190839352 .statediagram-note text{fill:black;}#publish-mermaid-5-1793190839352 .statediagram-note .nodeLabel{color:black;}#publish-mermaid-5-1793190839352 .statediagram .edgeLabel{color:red;}#publish-mermaid-5-1793190839352 [id$=\”-dependencyStart\”],#publish-mermaid-5-1793190839352 [id$=\”-dependencyEnd\”]{fill:#333333;stroke:#333333;stroke-width:1;}#publish-mermaid-5-1793190839352 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].statediagram-cluster rect.outer{rx:5px;ry:5px;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 .node .neo-node{stroke:#9370DB;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node rect,#publish-mermaid-5-1793190839352 [data-look=\”neo\”].cluster rect,#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-5-1793190839352 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}结果正确结果错误
连接设备
执行命令
检查结果
成功
失败
记录错误
该状态图展示了命令执行的状态转换过程。
五、实战案例:配置 VLAN 与端口
5.1 需求分析
假设我们需要在多台 S5735 交换机上创建 VLAN 并配置端口。需求包括:
- 创建 VLAN 10
- 将端口 GigabitEthernet0/0/1 加入 VLAN 10
- 配置端口为 access 模式
5.2 代码实现
实现配置 VLAN 和端口的代码:
def configure_vlan_and_port(ssh, vlan_id, port):
commands = [
f"vlan {vlan_id}",
f"port GigabitEthernet0/0/{port}",
"port link-type access",
f"port default vlan {vlan_id}"
]
return safe_execute_commands(ssh, commands)
5.3 结果验证
验证配置是否成功:
def verify_configuration(ssh, vlan_id, port):
commands = [
f"display vlan {vlan_id}",
f"display port GigabitEthernet0/0/{port}"
]
return batch_execute_commands(ssh, commands)
#publish-mermaid-6-1793190839564{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-6-1793190839564 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-6-1793190839564 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-6-1793190839564 .error-icon{fill:#552222;}#publish-mermaid-6-1793190839564 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-6-1793190839564 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-6-1793190839564 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-6-1793190839564 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-6-1793190839564 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-6-1793190839564 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-6-1793190839564 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-6-1793190839564 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-6-1793190839564 .marker.cross{stroke:#333333;}#publish-mermaid-6-1793190839564 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-6-1793190839564 p{margin:0;}#publish-mermaid-6-1793190839564 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-6-1793190839564 .cluster-label text{fill:#333;}#publish-mermaid-6-1793190839564 .cluster-label span{color:#333;}#publish-mermaid-6-1793190839564 .cluster-label span p{background-color:transparent;}#publish-mermaid-6-1793190839564 .label text,#publish-mermaid-6-1793190839564 span{fill:#333;color:#333;}#publish-mermaid-6-1793190839564 .node rect,#publish-mermaid-6-1793190839564 .node circle,#publish-mermaid-6-1793190839564 .node ellipse,#publish-mermaid-6-1793190839564 .node polygon,#publish-mermaid-6-1793190839564 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-6-1793190839564 .rough-node .label text,#publish-mermaid-6-1793190839564 .node .label text,#publish-mermaid-6-1793190839564 .image-shape .label,#publish-mermaid-6-1793190839564 .icon-shape .label{text-anchor:middle;}#publish-mermaid-6-1793190839564 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-6-1793190839564 .rough-node .label,#publish-mermaid-6-1793190839564 .node .label,#publish-mermaid-6-1793190839564 .image-shape .label,#publish-mermaid-6-1793190839564 .icon-shape .label{text-align:center;}#publish-mermaid-6-1793190839564 .node.clickable{cursor:pointer;}#publish-mermaid-6-1793190839564 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-6-1793190839564 .arrowheadPath{fill:#333333;}#publish-mermaid-6-1793190839564 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-6-1793190839564 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-6-1793190839564 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-6-1793190839564 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-6-1793190839564 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-6-1793190839564 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-6-1793190839564 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-6-1793190839564 .cluster text{fill:#333;}#publish-mermaid-6-1793190839564 .cluster span{color:#333;}#publish-mermaid-6-1793190839564 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-6-1793190839564 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-6-1793190839564 rect.text{fill:none;stroke-width:0;}#publish-mermaid-6-1793190839564 .icon-shape,#publish-mermaid-6-1793190839564 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-6-1793190839564 .icon-shape p,#publish-mermaid-6-1793190839564 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-6-1793190839564 .icon-shape .label rect,#publish-mermaid-6-1793190839564 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-6-1793190839564 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-6-1793190839564 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-6-1793190839564 .node .neo-node{stroke:#9370DB;}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node rect,#publish-mermaid-6-1793190839564 [data-look=\”neo\”].cluster rect,#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-6-1793190839564 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-6-1793190839564 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}是否
开始
连接设备
下发 VLAN 配置命令
下发端口配置命令
验证配置
配置正确?
结束
记录错误
重新配置
该流程图展示了 VLAN 和端口配置的完整流程。
六、安全考虑与最佳实践
6.1 SSH 密钥管理
使用 SSH 密钥而非密码可以提高安全性。可以通过以下方式生成密钥对:
ssh-keygen -t rsa
6.2 配置备份与回滚
在修改配置前,建议先备份当前配置:
def backup_configuration(ssh, backup_path):
stdin, stdout, stderr = ssh.exec_command("display current-configuration")
config = stdout.read().decode('utf-8')
with open(backup_path, 'w') as f:
f.write(config)
return config
#publish-mermaid-7-1793190839724{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-7-1793190839724 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-7-1793190839724 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-7-1793190839724 .error-icon{fill:#552222;}#publish-mermaid-7-1793190839724 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-7-1793190839724 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-7-1793190839724 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-7-1793190839724 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-7-1793190839724 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-7-1793190839724 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-7-1793190839724 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-7-1793190839724 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-7-1793190839724 .marker.cross{stroke:#333333;}#publish-mermaid-7-1793190839724 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-7-1793190839724 p{margin:0;}#publish-mermaid-7-1793190839724 .entityBox{fill:#ECECFF;stroke:#9370DB;}#publish-mermaid-7-1793190839724 .relationshipLabelBox{fill:hsl(80, 100%, 96.2745098039%);opacity:0.7;background-color:hsl(80, 100%, 96.2745098039%);}#publish-mermaid-7-1793190839724 .relationshipLabelBox rect{opacity:0.5;}#publish-mermaid-7-1793190839724 .labelBkg{background-color:rgba(248.6666666666, 255, 235.9999999999, 0.5);}#publish-mermaid-7-1793190839724 .edgeLabel{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-7-1793190839724 .edgeLabel .label rect{fill:rgba(232,232,232, 0.8);}#publish-mermaid-7-1793190839724 .edgeLabel .label text{fill:#333;}#publish-mermaid-7-1793190839724 .edgeLabel .label{fill:#9370DB;font-size:14px;}#publish-mermaid-7-1793190839724 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-7-1793190839724 .edge-pattern-dashed{stroke-dasharray:8,8;}#publish-mermaid-7-1793190839724 .node rect,#publish-mermaid-7-1793190839724 .node circle,#publish-mermaid-7-1793190839724 .node ellipse,#publish-mermaid-7-1793190839724 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-7-1793190839724 .relationshipLine{stroke:#333333;stroke-width:1px;fill:none;}#publish-mermaid-7-1793190839724 .marker{fill:none!important;stroke:#333333!important;stroke-width:1;}#publish-mermaid-7-1793190839724 [data-look=neo].labelBkg{background-color:rgba(248.6666666666, 255, 235.9999999999, 0.5);}#publish-mermaid-7-1793190839724 .node .neo-node{stroke:#9370DB;}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node rect,#publish-mermaid-7-1793190839724 [data-look=\”neo\”].cluster rect,#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-7-1793190839724 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-7-1793190839724 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}包含包含包含
设备
string
hostname
string
ip_address
配置
string
timestamp
string
backup_path
VLAN
int
vlan_id
string
name
端口
string
interface_name
int
vlan_id
string
mode
该 ER 图展示了设备、配置、VLAN 和端口之间的关系。
七、性能优化与扩展
7.1 并发连接优化
使用多线程或异步编程可以提高并发性能:
import threading
from concurrent.futures import ThreadPoolExecutor
def concurrent_execute(ips, username, password, commands):
results = {}
with ThreadPoolExecutor(max_workers=10) as executor:
futures = {executor.submit(execute_on_device, ip, username, password, commands): ip for ip in ips}
for future in concurrent.futures.as_completed(futures):
ip = futures[future]
results[ip] = future.result()
return results
7.2 配置模板化
使用 Jinja2 模板引擎可以简化配置生成:
from jinja2 import Template
vlan_template = Template("""
vlan {{ vlan_id }}
name {{ vlan_name }}
""")
port_template = Template("""
port GigabitEthernet0/0/{{ port }}
port link-type access
port default vlan {{ vlan_id }}
""")
#publish-mermaid-8-1793190839918{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#publish-mermaid-8-1793190839918 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#publish-mermaid-8-1793190839918 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#publish-mermaid-8-1793190839918 .error-icon{fill:#552222;}#publish-mermaid-8-1793190839918 .error-text{fill:#552222;stroke:#552222;}#publish-mermaid-8-1793190839918 .edge-thickness-normal{stroke-width:1px;}#publish-mermaid-8-1793190839918 .edge-thickness-thick{stroke-width:3.5px;}#publish-mermaid-8-1793190839918 .edge-pattern-solid{stroke-dasharray:0;}#publish-mermaid-8-1793190839918 .edge-thickness-invisible{stroke-width:0;fill:none;}#publish-mermaid-8-1793190839918 .edge-pattern-dashed{stroke-dasharray:3;}#publish-mermaid-8-1793190839918 .edge-pattern-dotted{stroke-dasharray:2;}#publish-mermaid-8-1793190839918 .marker{fill:#333333;stroke:#333333;}#publish-mermaid-8-1793190839918 .marker.cross{stroke:#333333;}#publish-mermaid-8-1793190839918 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#publish-mermaid-8-1793190839918 p{margin:0;}#publish-mermaid-8-1793190839918 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#publish-mermaid-8-1793190839918 .cluster-label text{fill:#333;}#publish-mermaid-8-1793190839918 .cluster-label span{color:#333;}#publish-mermaid-8-1793190839918 .cluster-label span p{background-color:transparent;}#publish-mermaid-8-1793190839918 .label text,#publish-mermaid-8-1793190839918 span{fill:#333;color:#333;}#publish-mermaid-8-1793190839918 .node rect,#publish-mermaid-8-1793190839918 .node circle,#publish-mermaid-8-1793190839918 .node ellipse,#publish-mermaid-8-1793190839918 .node polygon,#publish-mermaid-8-1793190839918 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#publish-mermaid-8-1793190839918 .rough-node .label text,#publish-mermaid-8-1793190839918 .node .label text,#publish-mermaid-8-1793190839918 .image-shape .label,#publish-mermaid-8-1793190839918 .icon-shape .label{text-anchor:middle;}#publish-mermaid-8-1793190839918 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#publish-mermaid-8-1793190839918 .rough-node .label,#publish-mermaid-8-1793190839918 .node .label,#publish-mermaid-8-1793190839918 .image-shape .label,#publish-mermaid-8-1793190839918 .icon-shape .label{text-align:center;}#publish-mermaid-8-1793190839918 .node.clickable{cursor:pointer;}#publish-mermaid-8-1793190839918 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#publish-mermaid-8-1793190839918 .arrowheadPath{fill:#333333;}#publish-mermaid-8-1793190839918 .edgePath .path{stroke:#333333;stroke-width:1px;}#publish-mermaid-8-1793190839918 .flowchart-link{stroke:#333333;fill:none;}#publish-mermaid-8-1793190839918 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-8-1793190839918 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#publish-mermaid-8-1793190839918 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-8-1793190839918 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#publish-mermaid-8-1793190839918 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#publish-mermaid-8-1793190839918 .cluster text{fill:#333;}#publish-mermaid-8-1793190839918 .cluster span{color:#333;}#publish-mermaid-8-1793190839918 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#publish-mermaid-8-1793190839918 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#publish-mermaid-8-1793190839918 rect.text{fill:none;stroke-width:0;}#publish-mermaid-8-1793190839918 .icon-shape,#publish-mermaid-8-1793190839918 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#publish-mermaid-8-1793190839918 .icon-shape p,#publish-mermaid-8-1793190839918 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#publish-mermaid-8-1793190839918 .icon-shape .label rect,#publish-mermaid-8-1793190839918 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#publish-mermaid-8-1793190839918 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#publish-mermaid-8-1793190839918 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#publish-mermaid-8-1793190839918 .node .neo-node{stroke:#9370DB;}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node rect,#publish-mermaid-8-1793190839918 [data-look=\”neo\”].cluster rect,#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].swimlane.cluster rect{filter:none;}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node path{stroke:#9370DB;stroke-width:1px;}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node .neo-line path{stroke:#9370DB;filter:none;}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].node circle .state-start{fill:#000000;}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-8-1793190839918 [data-look=\”neo\”].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#publish-mermaid-8-1793190839918 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}是否
配置模板
Jinja2 模板引擎
生成配置命令
下发到设备
验证配置
成功?
完成
错误处理
重新生成
该流程图展示了配置模板化的流程。

