让我们一起探索Django的自动化运维秘密吧!

1 引言

最近,我尝试把那些用 AI 写的小工具搬到网页上,想着能更方便地日常操作。于是,我决定从 Django 开始试试。

2 界面风格与数据库选择

2.1 界面设计

整个界面分成两部分,左边是功能菜单,右边则是展示和互动区域。整体采用浅色系,背景是白色的,尽量避免 AI 常用的紫色渐变。

让我们一起探索Django的自动化运维秘密吧!
巡检数据分析功能

在 Django 里,所有需要的图片和 CSS 文件都被称为静态资源,放在 app 目录里的 static 文件夹中。

让我们一起探索Django的自动化运维秘密吧!

这个小狮子 LOGO 是豆宝生成的,狮毛里有代表网络的星状拓扑,嘴巴下方有齿轮象征 devops,脑门上则有个 AI 芯片,我特别喜欢这个设计。

让我们一起探索Django的自动化运维秘密吧!

2.2 数据库选择

之前的 Python 代码用 JSON 数据格式(因为我实验的 Juniper 设备原生支持 JSON,同时 AI 还帮我生成了一个 HTML 用于转换 Excel 和 JSON 数据),体验相当顺畅。

这次我选择了 MySQL 作为数据库(其实我对 MySQL不太熟,正好借此机会学习一下)。Django 通过 ORM 来翻译并执行 MySQL 语句,这样操作起来比直接写 SQL 轻松多了。

让我们一起探索Django的自动化运维秘密吧!
Django ORM

数据 AI 是怎么处理旧数据的呢?它用 PyYAML 把 inventory 目录下的 hosts 和 group 两个 yaml 文件写入到数据库表中。

pip install PyYAML
Python manage.py import_h3c_switches --clear
MySQL -u root -p 密码 -e 「USE web_tool; SELECT switch_name, hostname, platform, username, device_type, port, timeout FROM h3c_switch LIMIT 10;」
MySQL -u root -p 密码 -e 「USE web_tool; SELECT COUNT(*) as total_switches FROM h3c_switch;」
让我们一起探索Django的自动化运维秘密吧!
数据库展示

同时,创建在 MySQL 中的数据还可以通过超级用户在 Django 的后台管理,这样管理起来更加方便。

让我们一起探索Django的自动化运维秘密吧!

3 功能与架构展示

3.1 Django 项目的结构:

web_tool/
├── app02/                    # 应用 包含了所有的 py 代码
│   ├── __init__.py
│   ├── admin.py             Django 默认提供了 admin 后台管理 非常好用
│   ├── apps.py              app 启动类
│   ├── migrations      
│   ├── models.py
│   ├── tests.py          
│   └── views.py          Python 函数
├── manage.py
└── web_project/
    ├── asgi.py       网络请求 
    ├── settings.py    项目配置
    ├── urls.py       url->和函数的对应关系
    └── wsgi.py    网络请求

3.2 URL 设置

在 urls.py 文件中定义 HTML 与 views 函数的对应关系。

让我们一起探索Django的自动化运维秘密吧!
path(『config_backup/』, views.config_backup, name=『config_backup』),

3.3 视图(VIEWS)

这里是功能实现的关键代码,负责接收用户的请求(request),处理之后给用户反馈(网页、数据或重定向)。

Django 的 render 函数负责最终将「渲染」后的 HTML 页面返回给用户的浏览器。它的作用是把 views 函数中的数据(context)和模板(template)结合,生成完整的 HTML 页面,反馈给发起请求的用户。

return render(request, 『app02/config_backup.HTML』, context)

3.4 模型类(Model)

主页展示了整个维护系统的统计信息,数据从哪里来的呢?通过以下代码从 MySQL 获取。

# 获取统计数据
    total_switches = h3c_switch.objects.count()
    context = {
        『app_name』: 『Leo』,
        『total_switches』: total_switches,
    }
    return render(request, 『app02/index.HTML』, context)

Django 的模型类(Model)对应数据库中的一张表(比如存储交换机信息的表)。objects 可以理解为 ORM 用 Python 语言操作 MySQL 的接口。count 方法用于统计数量。

那么什么是 model 呢?Model 是 Django 中用来定义数据库结构的 Python 类,它相当于数据库的蓝图,决定了:

  1. 表结构:数据库里有哪些表
  2. 字段类型:每张表包含哪些列(如文本、数字、日期等)
  3. 数据关系:表与表之间是如何关联的(如一对一、一对多)
class h3c_switch(models.Model):
    switch_name = models.CharField(max_length=100, verbose_name=『交换机名称』, help_text=『交换机的标识名称』)
    hostname = models.CharField(max_length=100, verbose_name=『主机名/IP 地址』, help_text=『交换机的 IP 地址或主机名』)
    platform = models.CharField(max_length=50, verbose_name=『平台型号』, help_text=『交换机的平台型号』)
    username = models.CharField(max_length=50, verbose_name=『用户名』, help_text=『登录交换机的用户名』)
    password = models.CharField(max_length=100, verbose_name=『密码』, help_text=『登录交换机的密码』)
    port = models.IntegerField(default=22, verbose_name=『端口号』, help_text=『连接端口号,默认 22』)
    device_type = models.CharField(max_length=50, default=『h3c』, verbose_name=『设备类型』, help_text=『设备类型标识』)
    timeout = models.IntegerField(default=30, verbose_name=『超时时间』, help_text=『连接超时时间(秒)』)

Django 会根据 Model 的定义自动生成 SQL 语句来创建数据库表,不需要手动写 SQL,这点真是太棒了。

有了数据,我们就可以通过 Model.objects 来进行增删改查的操作。

3.5 功能展示

登录和退出界面

让我们一起探索Django的自动化运维秘密吧!
让我们一起探索Django的自动化运维秘密吧!

配置备份

设备信息保存在 inventory 目录,这里直接把之前 nornir 项目的数据复制过来。

让我们一起探索Django的自动化运维秘密吧!

生成的配置备份存放在 media 目录下,文件夹用时间戳命名:

让我们一起探索Django的自动化运维秘密吧!

设备巡检

inventory 和配置备份的数据一致,巡检命令直接写在代码里,输出结果存到本地

  1. results 保存了每台设备的 txt 格式结果
  2. Excel 是所有设备的巡检数据统计结果(用于巡检分析的输入)
让我们一起探索Django的自动化运维秘密吧!

巡检分析

导入巡检模块的 Excel 表格后生成分析结果

结果分为四个表格(CPU/内存/温度/电源与风扇状态)展示在界面上,并提供完整的 PDF 下载选项。

让我们一起探索Django的自动化运维秘密吧!

TCP 检测分析

输入目标 IP 和端口,进行检测并生成 TCP 握手延迟和 RTT 等参数,以此分析网络延迟。

让我们一起探索Django的自动化运维秘密吧!

ACL 匹配功能

这是我最初想要的功能,输入源 IP 和端口,查询源 IP 在两个 IRB 接口下的 ACL 所匹配的 filter 和 action 动作。因为之前已经写过相关的 py 代码,所以直接把成熟的代码扔给了 Qoder,写出的 Django 函数一次就成功了。

让我们一起探索Django的自动化运维秘密吧!

4 AI 代码解析

4.1 首页(index)

首先是我们的首页,先检查用户是否已登录,如果没有,就重定向到登录界面。

def index(request):
    
    # 使用session来存储当前的登录状态
    if not request.session.get('user_logged_in'):    
        return redirect('app02:user_login')

4.2 配置备份

老朋友 Nornir

 # 初始化Nornir 获取到设备列表
            nr = backup_tool.initialize_nornir()
            host_list = list(nr.inventory.hosts.keys())

开始执行配置备份

# 执行配置备份
            if is_ajax:
                messages.info(request, '开始备份配置文件...')
            logger.info(f"开始执行配置备份,备份目录: {backup_dir}")
            backup_results = backup_tool.backup_all_devices(backup_dir)
            logger.info(f"配置备份完成: 成功 {backup_results['success']}, 失败 {backup_results['failed']}")

这里 AI 调用了 backup_tool 对象的 backup_all_devices 方法。这个方法封装了与网络设备交互的逻辑,通过 SSH 登录设备并拉取配置,backup_dir 参数指定了备份文件的存放目录。

让我们一起探索Django的自动化运维秘密吧!
这些方法其实藏在了代码里,并没有直接暴露在views中

在这里有个判断,叫做if is ajax,你知道AJAX请求吗?简单来说,它是一种网络技术,能让网页在不刷新的情况下,从服务器拉取数据并更新部分内容。这种方式大大提升了用户的互动体验。

if is_ajax:
    这个判断检查当前请求是否是一个AJAX请求。
    messages.info(request, '  开始备份配置文件...'): 

如果是AJAX请求,Django的消息框架会悄悄地弹出一条提示,告诉用户备份已经开始了,即使页面没有刷新,也能让用户感受到良好的交互体验。

让我们一起探索Django的自动化运维秘密吧!
通过消息窗口反馈执行进度

4.3 设备巡检

首先得创建一个存放结果的目录。

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
inspection_dir = os.path.join(settings.MEDIA_ROOT, 'h3c_inspe', timestamp)
os.makedirs(inspection_dir, exist_ok=True)

我们用时间戳来生成一个独一无二的巡检目录,目录路径为:MEDIA_ROOT/h3c_inspe/YYYYMMDD_HHMMSS。同时,AI还加了一行代码,确保这个目录是存在的。

inspection_tool = H3CDeviceInspection()
nr = inspection_tool.initialize_nornir()
host_list = list(nr.inventory.hosts.keys())

老朋友Nornir又来了,首先要初始化Nornir网络自动化框架,然后获取设备列表。

connection_results = inspection_tool.test_connection()
connected_devices = []
failed_devices = []

for host, result in connection_results.items():
    if result["status"] == "success":
        connected_devices.append(host)
        # 发送成功消息
    else:
        failed_devices.append(host)
        # 发送失败消息

我之前的代码没有提示功能,Qoder在这里发挥了创意,增加了用户交互的信息。通过test_connection来测试所有设备的连接状态,连接结果会被分类记录成功与失败,并实时发送状态消息(在AJAX模式下)。

inspection_results = inspection_tool.inspect_all_devices(inspection_dir)

接下来调用inspect_all_devices方法来执行巡检命令,并将结果存储到(inspection_dir)里。

def inspect_all_devices(self, inspection_dir: str) -> dict:

不过这里有个小问题,处理Excel数据的代码并没有直接在views主代码中,而是包含在inspect_all_devices里。

 results = self.nr.run(
 task=self.inspect_single_device
            )

执行巡检结果的代码其实是用inspect_single_device这个函数,得继续找下一个函数。

def inspect_single_device(self, task: Task) -> Result:


# 执行所有巡检命令
            commands = [
                "display version",
                "display cpu-usage", 
                "display memory",
                "display environment",
                "display fan",
                "display power"
            ]
            
            output = ""
            for cmd in commands:
                result = task.run(
                    task=netmiko_send_command,
                    command_string=cmd,
                    use_textfsm=False,  # 不单独使用TextFSM解析
                    read_timeout=20
                )

关于textfsm的模板,我们早已准备好了。

def _parse_device_output(self, filename, template_path):

这个_parse_device_output函数是用来解析数据的核心引擎,它负责把网络设备的原始命令行输出转化为结构化的数据。

with open(template_path, encoding='utf-8') as f:
    fsm = textfsm.TextFSM(f)

接下来要加载模板。

raw_data = Path(filename).read_text(encoding='utf-8')

读取巡检文件的内容。

parsed = fsm.ParseText(raw_data)

最后将数据格式化成我们需要的结构。

df = pd.DataFrame(all_data)  # 将数据列表转换为DataFrame
df.to_excel(writer, index=False, sheet_name='设备巡检结果')   #将DataFrame写入Excel文件
让我们一起探索Django的自动化运维秘密吧!
整个巡检代码的流程

4.4 巡检结果分析

首先看看巡检代码的输出结果,我们希望通过分析和处理这些结果,获取可视化图表和异常设备的数据。

让我们一起探索Django的自动化运维秘密吧!

页面还会提供一个窗口,让用户上传这个Excel表格。

    if request.method == 'POST':
        if 'excel_file' not in request.FILES:
            messages.error(request, '请选择要上传的Excel文件')
            return render(request, 'app02/inspection_analysis.html', context)
        
        excel_file = request.FILES['excel_file']

接着,我们就开始处理数据,比如针对CPU进行分析:

def _generate_cpu_analysis(self, df, pdf):
来源:知乎
原文标题:Django自动化运维分享
声明:
文章来自网络收集后经过ai改写发布,如不小心侵犯了您的权益,请联系本站删除,给您带来困扰,深表歉意!

发表评论