
Fleet Flask Plotly/Dash用 REST API 构建自定义主机状态可视化仪表盘【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet本文介绍如何跳出 Fleet 自带的 Web UI基于 Fleet REST API 采集主机遥测数据用 Flask 作为 Web 框架、DashPlotly作为可视化层搭建一个带交互式在线/离线状态过滤的自定义仪表盘。读完本文你将掌握 Fleet API 的鉴权方式与主机列表端点的参数用法、从 API 到图表的数据流以及可复制的本地运行步骤并了解如何进一步扩展到软件清单等其他端点。背景为什么在 Fleet REST API 之上做自定义仪表盘Fleet 的设计原则之一是UI 里能做的事情REST API 里都能做。Fleet 官方文档 REST API 开篇即说明 Use the Fleet APIs to automate Fleet并完整列出了各资源的路由、参数与响应示例。这意味着当你想做一些 UI 没有直接提供的展示形态——比如一张面向管理层的主机在线率看板、一份按团队切分的图表页——不需要额外中间件直接对 REST API 发请求即可拿到结构化 JSON。Fleet 团队此前已经演示过通过 Tines 工作流调用 REST API 的场景仓库内对应 Tines 集成文档也演示过用 Okta Workflows 调用 API 生成每日 OS 报告参见 Okta Workflows 示例文章。本文聚焦另一类场景数据可视化。市场上有不少商业数据可视化工具但本文刻意不绑定任何特定方案只用开源组件证明一件事连接 Fleet API、采集遥测数据并渲染成图表门槛非常低。技术栈整套方案由三个开源组件组成组件角色说明Fleet REST API数据源提供主机、软件等资源的 JSON 接口文档见 docs/REST API/rest-api.mdFlaskPython Web 框架承载仪表盘页面Dash 应用本身就跑在 Flask 之上Plotly / Dash图表与应用框架MIT 许可的开源绘图库Dash 提供布局组件与回调callback机制适合做交互式看板选择 Dash 的动机在于它把 Flask 服务 前端交互 压缩到纯 Python 里用声明式布局组件和回调函数就能实现 改一下下拉框 → 图表联动刷新 的交互而不需要单独写前端工程。本文的示例代码与概念源自社区经典的 Python Dash 教程思路Real Python 的 Python Dash 系列只需把数据源从示例用的牛油果数据换成 Fleet 的主机数据即可。前置条件与本地环境准备示例运行需要一个可访问的 Fleet 实例与本地开发环境一台本地 macOS 开发工作站其他平台同理已安装 Python 3可用 Homebrew 安装一个已部署并可登录的 Fleet 服务器以及一个可获取 API token 的账号示例代码仓库社区维护的fleetdash示例工程包含fleetdash.py单文件应用。开发 Python Web 应用时建议先创建虚拟环境venv再安装依赖把requests、plotly、dash等库隔离在独立环境中。目标一个带交互过滤的主机状态仪表盘示例应用只做三件事但完整覆盖了 API → 数据 → 图表 → 交互 的链路创建一个 Flask 应用数据来自单个 Fleet REST API 端点主机列表使用 Dash 的核心组件与 HTML 组件搭建页面布局通过 callback 实现交互用下拉框按online / offline状态过滤主机图表即时更新。动手安装依赖与启动克隆示例仓库后在激活的 venv 中安装依赖(venv) % pip install requests json pandas plotly dash datetime numpy进入仓库目录直接启动应用(venv) % python3 ./fleetdash.py一切正常时终端会输出(venv) % python3 ./fleetdash.py Dash is running on http://127.0.0.1:8050/ * Serving Flask app ‘fleetdash’ * Debug mode: on用浏览器打开http://127.0.0.1:8050/即可看到上面开头那张截图所示的仪表盘主机状态分布图表配合状态过滤下拉框。示例应用的核心代码结构讲解版示例仓库不在本仓库内这里按原文档描述的功能流程给出一个简化的核心结构讲解版帮助你理解fleetdash.py内部在做什么、也方便你把数据源换成自己的 Fleet 实例import dash import pandas as pd import plotly.express as px import requests from dash import dcc, html FLEET_URL http://localhost:8080 # 换成你的 Fleet 实例地址 API_TOKEN your-token # Fleet UI My account 页获取 HEADERS {Authorization: fBearer {API_TOKEN}} def fetch_hosts(): 调用主机列表端点把 JSON 展平为 DataFrame。 resp requests.get( f{FLEET_URL}/api/latest/fleet/hosts, headersHEADERS, params{page: 0, per_page: 50}, timeout30, ) resp.raise_for_status() rows [ { hostname: h[hostname], platform: h[platform], status: h[status], # online / offline / mia / missing os_version: h[os_version], } for h in resp.json()[hosts] ] return pd.DataFrame(rows) app dash.Dash(__name__) df fetch_hosts() app.layout html.Div([ html.H1(Fleet Host Dashboard), # 交互式过滤全部 / 在线 / 离线 dcc.Dropdown( idstatus-filter, options[ {label: All, value: all}, {label: Online, value: online}, {label: Offline, value: offline}, ], valueall, ), html.Div(idchart-container), ]) app.callback( dash.dependencies.Output(chart-container, children), dash.dependencies.Input(status-filter, value), ) def update_chart(status): view df if status all else df[df[status] status] chart px.histogram(view, xstatus, titleHosts by status) return dcc.Graph(figurechart) if __name__ __main__: app.run(debugTrue)这个结构与原文档的三项目标一一对应requests负责打 Fleet APIpandas把 JSON 列表整理成可过滤的表格px.histogram出图app.callback让下拉框的变化驱动图表重算。把FLEET_URL指向你自己的 Fleet 实例、API_TOKEN换成真实 token 后即可得到与截图同形态的页面。Fleet REST API 侧的关键细节以当前仓库文档为准鉴权API Token Bearer 头所有 API 请求默认要求 API token 鉴权token 绑定到你的 Fleet 用户账号。获取方式有两种见 REST API 文档 的 Authentication 一节在 Fleet UI 的 My account 页面/profile点击 Get API token或调用登录端点POST /api/v1/fleet/loginSSO/MFA 用户不支持走 API 登录只能从 UI 取 token。拿到 token 后每个请求都要带上Authorization: Bearer your token上面示例代码中的HEADERS就是在做这件事。主机列表端点GET /api/v1/fleet/hosts仪表盘的数据源就是主机列表端点。当前仓库文档中该端点支持丰富的查询参数与做图表最相关的有参数类型说明page/per_pageinteger分页文档建议配合query搜索或device_mappingtrue等昂贵操作时把per_page压到 50避免压垮 Fleet 服务器order_key/order_directionstring排序字段可为 hosts 表任意列与方向asc/descstatusstring按主机状态过滤new、online、offline、mia、missing或enrolledquerystring按hostname、hardware_serial、uuid、ipv4、终端用户邮箱等字段搜索populate_software/populate_policies/populate_users/populate_labelsstring/boolean控制是否附带软件、策略、用户、标签数据populate_software返回数据量大需要漏洞明细时可取without_vulnerability_details一个典型请求形如GET /api/v1/fleet/hosts?page0per_page100order_keyhostname响应中的每台主机都带有status字段online/offline等、hostname、platform、os_version、uuid等信息正是仪表盘需要展示的列。值得注意的是由于服务端已经支持status过滤如果你在 API 侧过滤而不是在 DataFrame 里过滤还能显著减少传输量——这是从文档参数表可以直接得到的优化方向。路径版本说明仓库当前文档以/api/v1/...作为端点路径如GET /api/v1/fleet/hosts、GET /api/v1/fleet/software/titles同时文档内资源 URL 中仍出现/api/latest/...形式如软件图标的icon_url。示例代码中使用哪个别名以你的 Fleet 版本实际行为为准本文档仓库的规范写法是/api/v1。可以接着做什么原文档列出的扩展方向结合当前仓库文档可以落得更实接入软件端点主机列表只是起点。Fleet 还提供软件列表端点GET /api/v1/fleet/software/titles见 REST API 文档 的 List software 一节支持vulnerable、available_for_install、self_service、platform、query等过滤参数按hosts_count排序默认降序——非常适合做一张 安装最广泛的软件 / 带漏洞软件 图表和主机状态图并排放在同一块 Dash 布局里。给 Flask 应用加鉴权示例应用监听在127.0.0.1只适合本地演示。若要部署应参考 token-based authentication 的做法给 Dash 应用本身加登录并保证 Fleet API token 不写死在代码里例如从环境变量读取。部署把 Flask 应用部署到 AWS 或 Heroku 之类的托管环境配合定时刷新如 Dash 的Interval组件即可变成常驻监控页。探索其他开源看板方案例如基于 Grafana Prometheus 数据源做告警与可视化与本文的 直连 REST API 路线互补。更多 API 调用形态可参考仓库内的 Okta Workflows 每日 OS 报告文章 与 Tines 集成文档。小结这条 Fleet REST API → pandas → Dash/Plotly 的链路证明了几点Fleet 的 API 覆盖了 UI 的全部能力主机列表端点的status、query、分页参数天然适配做交互式图表用 Flask Dash 这类开源 Python 组件一个下午就能从官方文档的端点参数表走到一个可过滤的在线看板而 API token Bearer 头的鉴权模型、per_page限流建议等细节都直接写在本仓库的 REST API 文档 里照着做即可。如果你希望继续完善示例代码欢迎向示例仓库提交 PR 或在社区如 osquery / MacAdmins Slack作者dherder交流。【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考