From 55719ed9536fac9042acee91fffa03187e2a250c Mon Sep 17 00:00:00 2001 From: panjunlan Date: Wed, 18 Feb 2026 11:41:03 +0800 Subject: [PATCH] First Commit --- .env | 14 ++++++++++++++ README.md | 7 +++++++ config/settings.py | 33 +++++++++++++++++++++++++++++++++ main.py | 20 ++++++++++++++++++++ vcenter_connector.py | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 .env create mode 100644 README.md create mode 100644 config/settings.py create mode 100644 main.py create mode 100644 vcenter_connector.py diff --git a/.env b/.env new file mode 100644 index 0000000..1a6a97f --- /dev/null +++ b/.env @@ -0,0 +1,14 @@ +# vCenter配置(支持多个) +VCENTER_HOSTS=192.168.40.134 +VCENTER_USER=administrator@lan.com +VCENTER_PASSWORD=Root@2025 +# 快照保留天数 +SNAPSHOT_RETENTION_DAYS=15 +# 每台vCenter同时删除的快照数量限制 +MAX_DELETE_CONCURRENT=4 +# Excel导出路径 +# EXCEL_OUTPUT_PATH=/tmp/vm_snapshots_report.xlsx +EXCEL_OUTPUT_PATH=./vm_snapshots_report.xlsx +# 日志文件路径 +# LOG_FILE_PATH=/var/log/vm_snapshot_cleanup.log +LOG_FILE_PATH=./log/vm_snapshot_cleanup.log \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd4bfbe --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# 以下需求需要每个月执行一次,使用ansible实现,还是使用python代码实行好? +-[x] 获取所有vms +-[ ] 获取所有snapshots +-[ ] 筛选出15天(半个月)前的snapshots +-[ ] 以上内容以Excel表格的形式导出 +-[ ] 最后删除15天前的snapshot,并同时记录删除的snapshot日志信息 +-[ ] 需要控制每台vCenter不可以同时删除超过4个快照 \ No newline at end of file diff --git a/config/settings.py b/config/settings.py new file mode 100644 index 0000000..d9d6935 --- /dev/null +++ b/config/settings.py @@ -0,0 +1,33 @@ +import os +from datetime import datetime, timedelta +from dotenv import load_dotenv + +# 加载.env文件 +load_dotenv() + +# ========== 基础配置 ========== +# vCenter配置 +VCENTER_HOSTS = os.getenv('VCENTER_HOSTS', '').split(',') +VCENTER_USER = os.getenv('VCENTER_USER', '') +VCENTER_PASSWORD = os.getenv('VCENTER_PASSWORD', '') + +# 快照策略配置 +SNAPSHOT_RETENTION_DAYS = int(os.getenv('SNAPSHOT_RETENTION_DAYS', 15)) +MAX_DELETE_CONCURRENT = int(os.getenv('MAX_DELETE_CONCURRENT', 4)) + +# 输出路径配置 +EXCEL_OUTPUT_PATH = os.getenv('EXCEL_OUTPUT_PATH', '/tmp/vm_snapshots_report.xlsx') +LOG_FILE_PATH = os.getenv('LOG_FILE_PATH', '/var/log/vm_snapshot_cleanup.log') + +# 计算快照过期时间(全局变量) +EXPIRE_DATE = datetime.now() - timedelta(days=SNAPSHOT_RETENTION_DAYS) + +# 验证必要配置 +def validate_config(): + """验证配置是否完整""" + required = [ + VCENTER_HOSTS, VCENTER_USER, VCENTER_PASSWORD, + SNAPSHOT_RETENTION_DAYS, MAX_DELETE_CONCURRENT + ] + if not all(required) or '' in VCENTER_HOSTS: + raise ValueError("配置不完整,请检查.env文件中的vCenter信息和策略配置") \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..3ce71a8 --- /dev/null +++ b/main.py @@ -0,0 +1,20 @@ +# 这是一个示例 Python 脚本。 + +# 按 Shift+F10 执行或将其替换为您的代码。 +# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。 + + +def print_hi(name): + # 在下面的代码行中使用断点来调试脚本。 + print(f'Hi, {name}') # 按 Ctrl+F8 切换断点。 + + +# 按装订区域中的绿色按钮以运行脚本。 +if __name__ == '__main__': + print_hi('PyCharm') + +# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助 + + + + diff --git a/vcenter_connector.py b/vcenter_connector.py new file mode 100644 index 0000000..1750a0c --- /dev/null +++ b/vcenter_connector.py @@ -0,0 +1,40 @@ +from pyVim.connect import SmartConnect, Disconnect +from pyVmomi import vim +from config.settings import VCENTER_USER, VCENTER_PASSWORD +from utils.logger import logger + + +def connect_to_vcenter(vcenter_host): + """ + 连接到指定的vCenter服务器 + :param vcenter_host: vCenter主机名/IP + :return: 成功返回ServiceInstance,失败返回None + """ + try: + # 禁用SSL证书验证(生产环境建议启用证书验证) + si = SmartConnect( + host=vcenter_host, + user=VCENTER_USER, + pwd=VCENTER_PASSWORD, + disableSslCertValidation=True + ) + if not si: + logger.error(f"❌ 无法连接到vCenter: {vcenter_host}(无返回实例)") + return None + + logger.info(f"✅ 成功连接到vCenter: {vcenter_host}") + return si + + except Exception as e: + logger.error(f"❌ 连接vCenter {vcenter_host} 失败: {str(e)}") + return None + + +def disconnect_from_vcenter(si): + """ + 关闭vCenter连接 + :param si: ServiceInstance实例 + """ + if si: + Disconnect(si) + logger.debug("已关闭vCenter连接") \ No newline at end of file