├── .gitignore ├── LICENSE ├── README.md ├── device_info_reader.py ├── devices_list.xlsx ├── get_latest_version.py ├── get_version.py ├── main.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | test.py 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # poetry 99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 103 | #poetry.lock 104 | 105 | # pdm 106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 107 | #pdm.lock 108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 109 | # in version control. 110 | # https://pdm.fming.dev/#use-with-ide 111 | .pdm.toml 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | # PyCharm 157 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 158 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 159 | # and can be added to the global gitignore or merged into this file. For a more nuclear 160 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 161 | #.idea/ 162 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 yanghua 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 获取华为固件版本,并在现网中对比版本,得到最新版本,并下载最新固件版本对应 MIB 文件 2 | 3 | ### 分析 4 | 5 | - 从Excel文件中读取所有设备的信息。 6 | - 连接到每个设备并获取其固件版本。 7 | - 去重版本,并比较所有版本,找到最新的固件版本。 8 | - 如果MIB文件库中没有对应版本,就直接下载比当前获取的最新版本还高的版本即可向下兼容。 9 | 10 | 11 | ### 如何使用 12 | 13 | - 把交换机的设备管理IP、3A用户和密码写入到devices_list.xlsx中。 14 | - 直接执行 main.py 入口函数。 15 | - 得到你当前环境中的交换机使用的最新固件版本。 16 | - 去对应的 mib 文件服务器中下载对应的最新固件版本 mib 文件。 17 | - 完成 mib 文件下载即可。 18 | 19 | ### 脚本依赖 20 | 21 | - pandas 22 | - netmiko -------------------------------------------------------------------------------- /device_info_reader.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # File: device_info_reader.py 3 | # Author: Neo 4 | # Created on: 2023-12-08 5 | # Description: 交换机连接信息格式化 6 | 7 | import pandas as pd 8 | 9 | def process_device_info_chunk(switch_info_df): 10 | # 用于存储交换机信息的列表 11 | devices = [] 12 | 13 | # 在 DataFrame 中迭代行 14 | for index, row in switch_info_df.iterrows(): 15 | device_info = { 16 | 'device_type': 'huawei', 17 | 'ip': row['IP'], 18 | 'username': row['Username'], 19 | 'password': row['Password'], 20 | 'port': 22, 21 | 'conn_timeout': 15, 22 | } 23 | devices.append(device_info) 24 | 25 | return devices -------------------------------------------------------------------------------- /devices_list.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robotneo/huawei_mib_down/ecf30dfb7e2c6a42962a86f89b4c3bbf4bb13017/devices_list.xlsx -------------------------------------------------------------------------------- /get_latest_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # File: get_version.py 3 | # Author: Neo 4 | # Created on: 2023-12-08 5 | # Description: 提取交换机固件最新版本 6 | 7 | import re 8 | 9 | def version_key(version): 10 | # 使用正则表达式拆分版本字符串为字母部分和数字部分 11 | match = re.match(r'([a-zA-Z]+)(\d+)(\d+)(\d+)(\d+)', version) 12 | 13 | if match: 14 | letters, num1, num2, num3, num4 = match.groups() 15 | return (letters, int(num1), int(num2), int(num3), int(num4)) 16 | else: 17 | return (version, 0) # 如果无法匹配,直接按原字符串比较 18 | 19 | def version_latest_version(versions): 20 | # 去重 21 | unique_versions = list(set(versions)) 22 | sorted_versions = sorted(unique_versions, key=version_key, reverse=True) 23 | # print(sorted_versions) 24 | return sorted_versions[0] -------------------------------------------------------------------------------- /get_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # File: get_version.py 3 | # Author: Neo 4 | # Created on: 2023-12-08 5 | # Description: 提取交换机固件版本 6 | 7 | import re 8 | from netmiko import ConnectHandler 9 | 10 | def parse_version(version_string): 11 | # 使用正则表达式匹配版本信息 12 | match = re.search(r'V\d{3}R\d{3}C\d{2}SPC\d{3}', version_string) 13 | # 提取匹配到的版本信息 14 | if match: 15 | version = match.group() 16 | return version 17 | else: 18 | print("未找到版本信息") 19 | 20 | def get_huawei_firmware_version(devices_format_info): 21 | # 存储交换机版本信息 22 | switch_versions = [] 23 | for device_info in devices_format_info: 24 | try: 25 | net_connect = ConnectHandler(**device_info) 26 | # 使用命令获取交换机固件版本信息 27 | version_output = net_connect.send_command('display version') 28 | # 从输出中提取固件版本(根据实际输出格式进行调整) 29 | lines = version_output.splitlines() 30 | for line in lines: 31 | if "VRP (R) software, Version" in line: 32 | firmware_version = line.split("Version")[1].strip() 33 | version_string = parse_version(firmware_version) 34 | # 解析版本信息 35 | switch_versions.append(version_string) 36 | except Exception as e: 37 | print(f"Error connecting to switch at {device_info['ip']}: {e}") 38 | finally: 39 | # 在 finally 块中确保关闭连接 40 | if net_connect: 41 | net_connect.disconnect() 42 | # 返回交换机所有固件版本 43 | return switch_versions -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # File: main.py 3 | # Author: Neo 4 | # Created on: 2023-12-08 5 | # Description: 提取交换机连接信息 6 | 7 | import pandas as pd 8 | import device_info_reader 9 | from netmiko import ConnectHandler 10 | import get_version 11 | import get_latest_version 12 | 13 | # 从 Excel 文件读取交换机信息 14 | def read_switch_info_from_excel(excel_file_path): 15 | df = pd.read_excel(excel_file_path) 16 | return df 17 | 18 | if __name__ == "__main__": 19 | text = read_switch_info_from_excel('devices_list.xlsx') 20 | devices_format_info = device_info_reader.process_device_info_chunk(text) 21 | versions= get_version.get_huawei_firmware_version(devices_format_info) 22 | print(get_latest_version.version_latest_version(versions)) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | netmiko==4.3.0 2 | pandas==2.1.3 --------------------------------------------------------------------------------