8. 呈现层#
VLAN 自动化已经运行了六周。网络团队为此感到自豪。每天早上,来自应用团队的三四个新服务请求到来,编排器在没有任何人敲键盘的情况下处理了它们。部署正常工作,交换机被配置好了,网络运行健康。
升级事件在周四到来。应用团队负责人在询问,当门户显示"已提交"时,为什么 VLAN 请求需要三到五个工作日。网络团队检查了他们的队列:零条待处理请求,所有部署成功。自动化在收到每个请求后二十分钟内就处理了。但 ServiceNow 工单仍然显示"进行中",因为没有人编写过会更新它们的集成。
自动化完成了它的工作,但结果是不可见的。
一周后,团队部署了一个快速的自助服务门户,让应用团队可以直接提交请求并查看状态。到中午他们在一小时内收到了四十七个 VLAN 请求,全部有效,格式正确。问题是:门户没有授权模型。它接受任何拥有 URL 的人的提交。所有请求都在一个拥有平台级管理员权限的单一 API 令牌下运行。没有速率限制、没有审批门、没有谁提交了什么的审计跟踪。
自动化运行了,但访问模型没有。
这两个失败都是呈现层的失败。一个是缺少反馈循环;另一个是缺少护栏。本章填补这一空白。
8.1. 基础概念#
8.1.1. 背景#
到目前为止涵盖的每个构建块都面向内部:面向其他模块或面向理解平台的工程师。Source of Truth (SoT) 为自动化系统保存网络意图。执行器将变更应用到设备。Observability 验证结果。Orchestrator 协调它们所有。每个模块都有一个 UI、一个 API 或两者兼有,设计给构建和运营平台的人,而不是所有需要与之交互的人。
Presentation (Layer) 层面向外部。它的工作是让平台对那些不需要了解内部机制的受众可访问:请求网络服务的应用团队、询问上季度发生了什么变更的安全审计员、在没有人工参与的情况下配置基础设施的 CI/CD 管道。
在第 3 章中,呈现模块位于 NAF 框架的边缘,面向人类和外部系统。第 6 章确立了可观测性可视化与呈现之间的边界:直接建立在网络遥测上的仪表板由于设计亲和性属于可观测性模块;这些仪表板如何向非工程师暴露、访问控制或嵌入门户是呈现关注的问题。第 7 章确立了异步工作流需要状态端点和通知钩子,呈现层提供这两者。
8.1.2. 目标#
呈现层服务于三个目标,直接映射到三个架构功能。
提供具有一致访问模型的稳定、已认证 API。 每个消费者,无论是人工还是机器,都应该通过一个版本化的、访问受控的合同与平台交互,该合同不会在没有通知的情况下改变。底层模块可以被替换、升级或重组;面向消费者的合同必须保持稳定。认证和授权在这个边界处执行,集中化而不是分散在每个工具中。
通过适合每种消费者类型工作流的界面服务每种消费者。 网络工程师和应用团队经理有不同的需求、不同的技术深度,以及对自动化如何与他们沟通的不同期望。呈现层提供多个界面:GUI 门户、Command Line Interface (CLI)、ChatOps 集成,所有这些都由同一 API 和同一访问模型支持,状态向发起行动的受众展示。
将平台与外部系统双向连接,并通过消费者已经使用的渠道返回结果。 应用团队已经在 ServiceNow 中工作。CI/CD 管道已经在版本控制系统中运行。平台应该在他们所在的地方满足他们:从他们的系统接收请求,并将结果发送回同一系统,而不是要求他们工作流中使用新工具。
8.1.3. 支柱#
三个支柱支撑这些目标,每个功能对应一个:
- API 层:基础:版本化、已认证、RBAC 执行、稳定合同。认证和多租户在这里执行,而不是每个工具独立执行。所有其他界面都建立在它之上。
- 客户端界面:所有面向消费者的界面(GUI 门户、CLI、移动端、ChatOps)作为同一底层 API 的不同形态。
- 集成和通知:外部系统连接(ITSM、CI/CD 管道、消息系统)和出站结果传递(Webhook、回调、推送通知)。
8.1.4. 范围#
呈现层展示内容,而不产生内容。
在范围内:
- API 层:所有消费者的认证、授权、版本控制和速率限制
- 建立在该 API 之上的客户端界面:GUI 门户、CLI、ChatOps、移动界面
- 外部集成:ITSM 工作流、CI/CD 管道钩子、Webhook 传递
- 出站通知:状态回调、推送告警、消息渠道事件
- 面向非工程师受众展示的运营仪表板(访问控制、受众范围和门户嵌入;底层指标架构属于第 6 章)
不在范围内:
- 数据生产(Observability,第 6 章)
- 配置渲染和模板处理(真实数据源,第 4 章)
- 工作流执行和审计记录生产(Orchestrator,第 7 章)
一个开始积累业务逻辑的呈现层(决定运行哪个工作流、根据网络模型验证输入、管理工作流状态)已经演变成了别的东西。这些职责属于编排器和真实数据源。如果门户开始编码网络策略或重试逻辑,架构边界就已经崩溃,平台将难以独立演进。
8.2. 功能#
三个目标和支柱通过三项核心功能来实现,每项功能直接对应一个目标和一个支柱:
- API 层:所有消费者的合同和访问模型
- 客户端界面:建立在该合同之上的界面
- 集成和通知:与外部系统的连接和出站传递
graph LR
subgraph Goals
direction TB
A1[Stable authenticated API and consistent access model]
A2[Right surface for each consumer type]
A3[Bidirectional integration with external systems]
end
subgraph Pillars
direction TB
B1[API layer: versioned, authenticated, stable]
B2[Client interfaces: GUI, CLI, chatops, mobile]
B3[Integrations and notifications: ITSM, CI/CD, webhooks]
end
subgraph Functionalities
direction TB
C1[API Layer]
C2[Client Interfaces]
C3[Integrations and Notifications]
end
A1 --> B1 --> C1
A2 --> B2 --> C2
A3 --> B3 --> C3
classDef row1 fill:#eef7ff,stroke:#4a90e2,stroke-width:1px;
classDef row2 fill:#ddeeff,stroke:#4a90e2,stroke-width:1px;
classDef row3 fill:#cce5ff,stroke:#4a90e2,stroke-width:1px;
class A1,B1,C1 row1;
class A2,B2,C2 row2;
class A3,B3,C3 row3;
8.2.1. API 层#
第 4 章深入介绍了 SoT 自己的 API:自动化系统如何查询意图数据、消费模式(REST、GraphQL、Webhook)以及网络配置的读写模型。这里讨论的 API 在目的上有所不同:它是面向整个自动化平台消费者的对外合同。SoT API 回答"网络应该是什么样子?",而呈现层 API 回答"自动化平台在做什么,我如何与它交互?“两者都可能是 REST API,但它们以不同的访问模型服务于不同的受众。
呈现层 API 是基础。每个消费者界面(门户、CLI、ITSM 表单、ChatOps 机器人、AI 智能体)都是这一层的调用者。认证、RBAC、版本控制和速率限制在这里执行。把它设计好,否则其上面的一切都会继承它的问题。
呈现层 API 不应该镜像内部模块接口。暴露直接代理到 SoT API 的 /v1/sot/vlans/ 端点,或包装编排器任务 ID 的 /v1/orchestrator/jobs/ 端点,会将消费者与内部实现细节绑定。当你用另一个模块替换一个模块时,每个存储了这些 ID 的 CI/CD 管道都必须更新。呈现层 API 应该暴露平台级概念:一个代表服务请求的 /v1/requests/ 端点,无论哪个编排器处理了它;一个返回 VLAN 当前状态的 /v1/services/vlan/ 端点,该状态从 SoT 和可观测性聚合而来,不暴露哪个模块提供了哪部分数据。消费者获得稳定的合同;内部实现可以在其背后自由演进。
8.2.1.1. API 暴露的内容#
API 暴露两类端点:
读取端点:工作流状态和历史、审计记录、从 SoT 和可观测性模块聚合的设备和服务状态。这些是应用团队用来检查请求状态、审计员用来审查变更记录、监控系统用来验证平台健康状况的查询。
写入端点:触发工作流、提交服务请求、批准或拒绝待处理的门控、取消正在运行的任务。写入端点需要更强的授权。不同角色应该有权访问不同的写入操作:应用团队成员可以提交请求但不能触发任意工作流;网络工程师可以批准待处理的门控但不能修改工作流定义。
读写区别也影响合同稳定性。读取端点必须无限期保持稳定:运行了一年的仪表板不应该因为上游模式变更而中断。写入端点必须明确版本化,在破坏性变更之前有弃用通知。
8.2.1.2. 版本控制和稳定性#
面向消费者的 API 必须进行版本控制。呈现层 API 是合同;模块内部是实现。编排器、SoT 或可观测性模块的内部重构不能破坏外部调用者。
标准方法:通过 URL 前缀(/v1/、/v2/)或 Accept 头进行版本控制,在定义的弃用窗口内维护上一个版本,并通过变更日志传达破坏性变更。一个调用 /v1/workflows/trigger 已经八个月的 CI/CD 管道,不应该在周一发现端点已经无通知地移动了。
8.2.1.3. 认证和授权#
认证回答:你是谁?授权回答:你被允许做什么?
许多团队先实现认证再实现授权,然后当有人在一个他们本不应该拥有的有效令牌下提交四十七个请求时,才发现"已认证"和"已授权"是不同的问题。
网络自动化平台的认证模式:
- SSO / LDAP 集成:企业标准。工程师和应用团队使用企业身份进行认证。无需管理单独的凭证,当有人离职时取消配置是自动的。
- OAuth 2.0 / OIDC:用于外部系统和网页门户用户。产生短期令牌而不是长期凭证。
- 范围化 API 令牌:用于 CI/CD 管道和自动化脚本的程序化访问。每个令牌都范围化为一组具有定义到期时间的特定权限。所有消费者使用的共享管理员令牌不是认证:它是一个无法在不同时破坏每个调用者的情况下撤销的共享密码。
通过 RBAC 授权。角色应该映射到运营职责,而不是工具能力。网络自动化的起始模型:
只读:查看任何数据,不触发任何操作操作员:触发预批准的工作流、批准门控、提交服务请求工程师:完整的工作流管理、SoT 写入访问、查看所有审计记录管理员:平台配置、用户管理、凭证轮换
每个角色继承其下面角色的所有权限。工程师可以做操作员能做的一切,另外还能写入 SoT 和管理工作流。
flowchart TD
RO[read-only]
OP[operator]
ENG[engineer]
ADM[admin]
RO -->|adds: trigger workflows + approve gates| OP
OP -->|adds: SoT write access + workflow management| ENG
ENG -->|adds: platform config + user management| ADM
style RO fill:#e8f5e9,stroke:#4caf50
style OP fill:#c8e6c9,stroke:#388e3c
style ENG fill:#a5d6a7,stroke:#2e7d32
style ADM fill:#66bb6a,stroke:#1b5e20
RBAC 在 API 边界处执行。底层模块只看到来自呈现层的已认证 API 调用;它们不独立管理消费者身份。多租户通过数据范围化实现:每个查询都按调用者的组织范围过滤。B 楼应用团队不应看到 A 楼零售团队的请求。这必须从一开始就设计好。将多租户改造到扁平数据模型是一个痛苦的重构项目。
审计跟踪应该捕获被拒绝的请求以及被批准的请求。谁尝试做什么并被拒绝,对合规来说与什么被允许同样重要。呈现层与第 7 章的工作流审计跟踪一起生成这条记录。第 12 章用密钥轮换、策略即代码和合规驱动的自动化流程扩展了这个模型。
8.2.1.4. 速率限制#
没有速率限制的自动化消费者会耗尽编排器的队列。那四十七个请求的事件不需要恶意行为者:只需要一个有动力的团队、一个 URL 和没有节流。
在 API 边界处进行速率限制:每令牌限制(每个消费者每分钟请求数)、突发限制(同时进行中的请求)以及特定操作限制(固件升级工作流每台设备一次不应运行超过一个实例)。速率限制响应应该返回带有 Retry-After 头的 HTTP 429,而不是几小时后以超时形式出现的静默队列填满。
8.2.1.5. REST、GraphQL 和 MCP 接口#
REST 是默认选择。它比 GraphQL 更简单地进行版本控制、推理和缓存。网络自动化团队很少需要 GraphQL 的消费者驱动查询灵活性,并为额外的复杂性付出有意义的运营成本。例外情况:如果平台服务于大量具有显著不同查询模式的不同消费者类型,GraphQL 可以减少过度获取和对多个专门端点的需求。这是一个合理的选择;它很少是正确的第一选择。
Model Context Protocol (MCP) 接口是呈现层的 AI 界面。就像人工操作员通过 CLI 访问平台,应用团队通过门户访问,基于 Large Language Model (LLM) 的智能体通过 MCP 服务器访问。智能体调用工具(查询工作流状态、触发修复、读取审计日志),调用顺序由其推理决定,受与任何其他调用者相同的 RBAC 模型约束。这直接连接到第 7 章(7.2.7 节)引入的智能体编排模式:呈现层的 MCP 服务器是使这些模式在整个平台上可操作的接口,无需智能体与每个单独模块之间的硬编码集成。
REST 和 MCP 的区别在于谁驱动交互。在 REST 集成中,消费者提前知道要调用哪些端点以及以什么顺序:CI/CD 管道调用 POST /v1/requests/vlan,然后轮询 GET /v1/requests/{id} 直到完成。序列在代码中是固定的。使用 MCP,基于 Large Language Model (LLM) 的智能体在运行时根据每次前面调用的结果决定调用哪些工具以及以什么顺序。消费者不是具有预定调用图的管道;它是一个在决定下一步做什么之前读取每个结果的推理系统。MCP 服务器定义可用工具及其模式;智能体决定如何使用它们。这使 MCP 适合开放式运营查询(“调查 B 楼和核心之间的连接问题”),如果实现为 REST,则需要开发人员预测每种可能的调用序列。它也使授权更加敏感:具有广泛工具访问权限的智能体可以以访问模型未明确设计的方式组合操作。RBAC 模型必须在工具级别应用,而不仅仅是在服务器级别。
8.2.2. 客户端界面#
客户端界面是建立在 API 之上的界面。它们是同一底层平台的不同形态,每种都适合不同的消费者类型。无论使用哪个界面,RBAC 模型都统一应用。
8.2.2.1. GUI 和自助服务门户#
网页门户是非工程师的主要界面。其设计原则是渐进式披露:向正确的受众展示适量的信息,而不暴露底层的复杂性。
应用团队看到三步视图:已提交、进行中、完成,状态详情用简单语言写道"预检在 24 台交换机上运行”,而不是 AWX 任务 ID。网络工程师看到每台设备的预检结果、带有批准或拒绝操作的审批门,以及需要时的完整工作流跟踪。管理员看到一切,包括配置和审计查询。
读取和写入界面有不同的设计要求。只读状态仪表板可以相对宽松:平台中的任何工程师都可以看到他们请求的当前状态。写入路径(提交请求、批准门控、取消正在运行的任务)需要输入验证、确认步骤,以及在提交操作之前清晰说明将发生什么。
我见过团队构建的门户,其中新服务请求表单上的提交按钮直接调用编排器 API,表单和工作流之间没有验证层。当用户提交与现有分配冲突的子网时,错误以未格式化的编排器堆栈跟踪的形式返回。呈现层应该在请求到达编排器之前根据 SoT 模型验证输入,并在验证失败时返回清晰的、可操作的错误。
采用风险在界面处最高。一个技术上正确但因为不符合团队已有工作方式而没有人使用的门户,比在每天早上所有人都打开的工具中进行更简单的集成价值更低。已经在 ServiceNow 中工作的应用团队,通过 ServiceNow 表单提交请求的一致性,会比通过他们必须单独学习和登录的新门户更高。已经使用 Slack 进行事件协调的工程团队,通过 Slack 消息对审批门通知的响应速度,会比通过需要额外认证的浏览器链接更快。熟悉度在采用时减少摩擦,在日常使用中降低错误率。在选择构建新界面和在用户已经熟悉的工具中满足用户之间,集成几乎总是正确的第一步。
8.2.2.2. CLI#
自动化平台的 CLI 不是设备 CLI(那是第 9 章的领域)。这是平台本身的命令行界面:工程师用来在不打开浏览器的情况下触发、检查和管理自动化的工具。
工程师偏好 CLI 的原因与他们对重复性工作偏好 Shell 脚本而不是 GUI 的原因相同:可组合性、速度和可脚本化。CLI 命令可以被别名化、通过管道传递给其他命令、在设备列表上循环、纳入操作手册,或与它管理的基础设施一起提交到仓库。门户点击不行。在凌晨 2 点的事件中,一个从记忆中五秒输入的命令,比一个需要二十秒导航和认证的门户更快。对于 CI/CD 管道,CLI 产生结构化退出代码(0 表示成功,非零表示失败),直接映射到管道通过/失败条件,无需任何解析。工程师也更信任 CLI 工具用于高风险操作:参数在 Shell 历史中可见、可审计且可重现。
即使门户存在,CLI 也有其位置。在凌晨 2 点的事件中,打开浏览器、登录、导航到工作流并逐步点击表单,比运行单个命令慢。对于 CI/CD 管道,CLI 比原始 API 调用更可取:它处理来自环境变量的认证,产生结构化退出代码,并在出现问题时提供人类可读的输出。
自动化平台 CLI 的设计原则:
- 一致的名词-动词命令结构(
workflow run、workflow status、request list),可预测地映射到 API 操作 - 通过
--json标志提供机器可读输出,使管道脚本可以解析结果 - 环境感知配置:API 端点和令牌从配置文件或环境变量读取,而不是硬编码到脚本中
- 应用于 API 的同一 RBAC 也应用于 CLI:具有操作员级别权限的令牌不能触发管理员级别的操作,无论使用哪个界面
8.2.2.3. 即时通讯和移动端#
Slack、Teams 和类似平台在网络自动化中扮演双重角色:它们既是通知渠道(呈现层将事件推送到其中),也是交互界面(工程师通过它们发送命令)。理解这种双重角色对架构很重要:接收告警通知的同一工作区应该支持审批流,减少已经监控这些渠道的工程师的上下文切换。
作为交互界面,消息平台通过将对话命令翻译成 API 调用的机器人来工作。机器人是精简的:它解析消息,在发送者的身份下将其映射到呈现层 API 调用,并为渠道格式化响应。三种模式在实践中运行良好:
- 审批流:带有"批准"和"拒绝"按钮的 Slack 消息让网络工程师在不离开 Slack 的情况下对待处理的门控采取行动。按钮点击调用带有工程师身份的 API 审批端点,通过平台与 Slack OAuth 的 SSO 集成解析。
- 状态查询:
@netbot status app-payments在格式化的渠道消息中返回当前工作流状态。 - 快速操作:
@netbot compliance-check building-b触发轻量级验证工作流并内联发布结果。
移动界面服务于门户和 CLI 无法覆盖的特定受众:在现场实际工作的数据中心技术员。在机架中更换线卡的技术员没有打开的笔记本电脑,他们的双手可能被占用,位置可能很尴尬。一个让他们扫描设备条形码、查看其当前自动化状态(由自动化管理、上次部署 14 天前、没有待处理变更)、确认物理更换,并触发适当修复工作流的移动应用,将物理工作连接到自动化平台,无需返回工作站。RBAC 模型适用:技术员的令牌范围化为其角色允许的操作。界面范围化为与现场相关的数据:设备身份、当前状态、待处理任务和简单触发操作,而不是完整的平台视图。
同一 RBAC 模型适用。机器人通过 SSO 认证工程师,并以范围化为该工程师角色的令牌转发请求。具有只读访问权限的工程师不能通过 Slack 触发工作流,就像通过门户一样。
作为通知目标,消息渠道接收来自呈现层的事件驱动更新:部署完成、失败告警、审批门请求和关键工作流错误。通知路由是配置策略,而不是硬编码映射。工程师在专用运营渠道中收到失败详情。应用团队通过 ITSM 工单收到完成状态。值班工程师通过 PagerDuty 收到关键故障。
移动界面遵循相同的模式。约束在于屏幕空间和交互模式,而不是架构。让工程师从手机批准待处理门控的移动审批界面调用与门户相同的 API,RBAC 模型不变。
8.2.2.4. 何时构建与接受内置 UI#
几乎每个模块都已经有了 UI。AWX 有工作流门户,Nautobot 有网页界面,Grafana 有仪表板。这些内置 UI 对于理解平台的工程师受众已经足够。构建专用呈现层的决定不应该是默认的。
一个实用的决策序列:
- 所有消费者都是已经使用模块 UI 的工程师吗?使用内置 UI,不要构建自定义门户。
- 非工程师需要请求或追踪自动化吗?你需要门户或 ITSM 集成。
- ITSM 已经是所有服务请求被管理的地方了吗?要么将 ITSM 作为你的呈现层,要么将其作为主要消费者进行集成。如果 ITSM 的工作流引擎、审批模型和通知系统足以满足你的请求模式,就让 ITSM 直接作为呈现层:自动化调用来自 ITSM 工作流内部,而不是来自其上的单独层。如果你需要更强的 API 合同、跨模块状态视图,或 ITSM 无法干净执行的 RBAC,ITSM 和模块之间的薄专用层提供这些属性,同时 ITSM 仍作为面向用户的界面。
- 你需要统一跨多个模块的 RBAC 吗?你需要具有集中认证的 API 层,无论你在其之上构建哪个客户端界面。
- 你能长期承诺维护自定义门户吗?如果不确定,从 ITSM 集成开始,只有当 ITSM 不足以满足你需要的访问模式时才构建门户。
- 消费者需要输入或查看 ITSM 表单无法表示的详细信息吗?复杂的输入字段(YAML 片段、拓扑参数、子网分配预览)、根据 SoT 模型进行内联验证,或带有每台设备下钻的丰富状态视图,通常超出了 ITSM 表单构建器能干净支持的范围。如果消费者经常需要这种级别的具体性,自定义门户就值得其运营成本。
当非工程师需要 ITSM 无法干净表达的访问,或者当你需要任何内置 UI 都无法提供的单一跨模块状态视图时,自定义门户值得构建。最常见的错误是在验证需求是真实的之前就构建它。
8.2.2.5. 文档和报告#
呈现层的两个相关只读输出服务于异步消费自动化知识的受众:文档消费者(需要了解网络服务当前状态的团队)和报告消费者(需要定期摘要和合规证据的管理人员和审计员)。
文档即代码模式在这里适用:使用模板语言(Jinja2、Markdown)从实时平台数据生成的文档,与自动化代码库一起进行版本控制,并在每次变更时重新生成。嵌入在生成文档中的 Mermaid 图表可以反映来自 SoT 的实际拓扑,而不是手动维护的绘图。同样,可观测性模块对原始指标应用的规范化逻辑(第 6 章介绍的)可以在这里重用:报告模板查询相同的规范化时间序列数据,为审计员生成表格摘要,无需重复规范化工作。
自动生成的文档将实时平台数据转换为可读、可共享的制品,无需手动维护。对于每个已部署的网络服务,生成的文档可以结合来自 SoT 的服务定义、来自可观测性的当前运营状态,以及来自编排器审计跟踪的变更历史。因为源数据始终是最新的,文档会自动保持最新。编排器中的工作流定义是另一个来源:文档生成器可以从工作流定义生成人类可读的操作手册,确保操作手册描述的内容与自动化实际执行的一致。
报告服务于需要定期摘要而不是实时视图的管理和合规受众。每周变更摘要(运行了多少工作流、成功率、平均持续时间、触及的设备)用于运营审查。合规导出(某个时期的所有变更记录,结构化用于审计提交)从编排器的审计跟踪和呈现层的授权日志中组装。SLA 和容量报告(配置时间趋势、按设备类别的错误率、待处理请求积压)用于容量规划和服务改进讨论。
运营仪表板按设计意图跨两章。第 6 章涵盖数据架构:采集什么、如何规范化,以及直接建立在遥测上面向工程师受众的仪表板。呈现层的参与从这些相同的仪表板向非工程师受众暴露时开始:将它们嵌入自助服务门户,范围化访问以便应用团队只看到他们的服务,或为现场使用构建移动友好的视图。底层指标保留在可观测性模块中;访问模型和界面上下文是呈现关注的问题。
与运营仪表板(第 6 章)的区别在于消费者和时间框架:仪表板向进行实时决策的工程师展示当前状态;文档和报告是非工程师异步消费的快照。底层数据可能相同,但界面和节奏不同。
8.2.3. 集成和通知#
呈现层以两个方向连接到外部系统:接收触发自动化的事件,以及将结果传递回发起请求的系统。这是消费者的工作流和平台的工作流汇聚的地方。
与 API 层的区别在于方向性和发起方。API 层处理入站请求:消费者调用平台并等待响应。集成和通知是关于平台向没有发起当前交互的系统发出信号:将状态更新推送到 ServiceNow 工单、向异步等待的 CI/CD 管道传递 Webhook 回调、将事件发布到监控特定服务的 Slack 渠道。API 层回答调用,这一节发送事件。两者使用相同的认证模型和 RBAC 边界;区别在于发起的方向。在小规模下,单个组件可以干净地处理两种模式。在更大规模下,出站事件传递(具有其重试逻辑、死信队列和订阅管理)通常成为具有自己运营关注点的独立组件,这就是为什么这个模型将两者分离为不同的功能。
8.2.3.1. ITSM 集成#
ITSM 平台在网络自动化架构中占据两个截然不同的位置,这个区别对设计很重要。在第一个位置,ITSM 平台是呈现层:其表单定义用户界面,其工作流引擎处理审批和通知,自动化 API 从 ITSM 工作流内部调用。在这个模型中没有外部集成,因为 ITSM 对呈现层来说不是外部的:它就是呈现层。在第二个位置,存在专用呈现层,ITSM 平台是它同步的消费者之一:请求通过 ITSM Webhook 到达,状态更新流回 ITSM 工单。第三个角色也很常见:ITSM 作为 SoT 数据源。当 CMDB 包含权威资产或服务记录时,SoT 可能将其作为联合数据源查询(在第 4 章中介绍),但这个角色中的 ITSM 在面向用户的自动化界面中不起任何作用。
本节的其余部分描述集成模式(第二个位置)。当 ITSM 平台的工作流引擎、审批模型和通知系统足以满足你的请求模式,并且你希望避免在用户和模块之间引入单独层时,ITSM 即呈现层模式(第一个位置)是正确的选择。
当消费者不应该需要知道自动化平台存在时,就要构建 ITSM 集成。应用团队已经在 ServiceNow 中工作,最可用的界面就是他们已经在使用的界面。
“新网络服务请求"的 ServiceNow 表单捕获 SoT 模型所需的确切字段,并以 API 层期望的结构化格式提交。表单是呈现层;消费者永远看不到 API 调用。提交后,呈现层根据 SoT 数据模型验证负载,认证 ITSM 集成使用的服务账户令牌,并将结构化请求转发给编排器。
请求触发后,工单应该近实时地反映工作流状态:“SoT 验证完成”,然后"预检运行中:24 台交换机”,然后"审批门:等待工程师签署",然后"完成:24/24 台交换机已配置"。这种双向同步比一次性 Webhook 更复杂。它要求呈现层订阅编排器状态事件,并使用持久事件订阅或轮询协调器将其翻译成工单更新。
在许多组织中,ITSM 工单是变更管理记录。呈现层必须确保工单包含足够的信息以满足变更管理要求,即使权威审计跟踪存在于编排器中。两条记录服务于不同受众:ITSM 工单服务于请求者和他们的经理;编排器审计记录服务于网络工程师和合规审计员。
ITSM 集成有其局限。它适合具有定义状态的结构化、表单驱动的请求工作流。它不适合实时运营查询、复杂工作流跟踪检查,或工程师需要快速迭代的高级用户操作。设计平台时要知道 ITSM 涵盖大多数非工程师请求,CLI 或门户涵盖其余的。
8.2.3.2. CI/CD 管道集成#
在定义的步骤调用呈现层 API、传递结构化输入并阻塞直到返回成功或失败结果的部署管道,在服务账户下运行,具有范围化令牌:足够触发网络工作流和读取其状态的权限,仅此而已。
这也是 CLI 在自动化上下文中赢得其位置的地方。运行 netauto workflow run vlan-deploy --params params.json --wait 的管道步骤,比内联构建 API 负载的原始 HTTP 调用更容易调试、更容易版本化、更容易替换。CLI 的结构化退出代码直接映射到管道步骤的通过或失败条件。
8.2.3.3. 推送通知和 Webhook 传递#
当工作流完成、到达审批门或失败时,呈现层通过正确的渠道通知正确的受众。通知路由是策略决定,而不是硬编码映射。工程师在专用 Slack 渠道中收到失败详情。应用团队通过工单更新收到完成状态。值班工程师通过 PagerDuty 收到关键故障。路由规则是配置,而不是代码。
Webhook 传递是传入 Webhook 的出站对应物。当触发工作流时注册了回调 URL 的调用者,在工作流完成时通过 HTTP POST 接收结果。传递保证、失败时的重试策略和负载模式是 API 合同的一部分。静默失败的回调(无重试、无日志、无告警)比根本没有回调更糟糕,因为调用者假设结果已被传递。
8.2.4. 解决方案概览#
此处列出的工具仅作解释性示例,不构成推荐。请根据团队能力、现有工具和运营约束来评估它们。
呈现章与第 2 部分中的任何其他章与解决方案概览的关系都不同。几乎没有专门作为呈现层存在的工具。每个模块都已经有了 UI。架构问题不是"我应该使用哪个呈现工具?“而是:何时接受每个模块的内置 UI,何时在它们之上构建专用呈现层?
在成熟的自动化平台中,两种模式并存。
内置模型:为其受众使用每个模块的内置 UI。工程师使用编排器门户进行工作流管理,SoT 网页界面用于清单,可观测性仪表板用于网络健康。当所有消费者都是理解工具的工程师,且不需要跨模块视图时,这种方法有效。运营开销低:不需要运行额外系统。
专用呈现模型:在模块之上构建或采用一个提供统一体验的层。当非工程师需要访问、需要在单一视图中显示跨模块状态,或 RBAC 要求不能干净映射到各工具内置权限时,这是必要的。
| 方法 | 示例 | 使用时机 |
|---|---|---|
| 每模块内置 UI | AWX 门户、Nautobot UI、Grafana | 工程师受众;每工具 RBAC 可接受;不需要跨模块视图 |
| ITSM 作为主界面 | ServiceNow、Jira Service Management | 企业组织;非工程师已在 ITSM 中;表单驱动的请求流程 |
| 自定义自助服务门户 | React/Vue 应用、Django 应用 | 非工程师需要访问;跨模块统一 RBAC;带审批流的自助服务 |
| API 网关 | Kong、AWS API Gateway、NGINX | 多消费者具有不同认证需求;速率限制;版本控制执行 |
| 网络原生门户 | Itential、NSO 北向 UI | 具有内置 RBAC 和 ITSM 适配器的网络中心平台 |
| 开发者门户 | Backstage | 需要统一入口点的大型组织,拥有许多内部平台 |
了解内置 UI 内部的内容对于自定义决策很重要。NetBox 建立在 Django(Python)之上;其网页界面和 REST API 是 Django 视图和 Django REST Framework 端点。Nautobot 有相同的血统。Infrahub 使用 FastAPI。这些 SoT 工具的"呈现组件"是成熟的网页框架:通过插件、自定义视图和序列化器扩展可以定制。这既是其优势(文档完善、生产级别),也是其约束(你在主要为 SoT 使用场景设计的框架内进行定制,而不是为自助服务门户使用场景)。
上表中的 ITSM 行代表 ITSM 作为呈现层,而不是作为外部集成。当组织已经将 ServiceNow 或 Jira Service Management 标准化为所有服务请求的入口时,ITSM 就是呈现层。自动化 API 是 ITSM 作为自己工作流一部分在内部调用的;用户和 ITSM 之间没有单独的网关。网关在 ITSM 和下游模块之间。
贯穿所有方法的一个架构原则:呈现层应该是精简的。它是界面,而不是系统。业务逻辑属于编排器和 SoT。呈现层翻译、认证和路由。一旦它开始做出自动化决策,边界就已经崩溃了。
8.3. 实施示例#
8.3.1. 两个界面、三个受众、一个平台#
我们在整个第 2 部分跟踪了园区网络。app-payments 的 VLAN 服务请求在第 4 章中在 SoT 中建模,在第 5 章中由执行器部署,在第 6 章中由可观测性验证,在第 7 章中由编排器端到端协调。从未解决的是三种不同受众如何与该工作流交互。
在这个园区中,呈现层由三个组件组成。ServiceNow 是更广泛组织的主要界面:应用团队完全在 ServiceNow 中提交请求和追踪状态,ServiceNow 作为其自身工作流自动化的一部分通过呈现层的 API 进行路由。带有审计视图的自定义门户服务于工程和合规受众:网络工程师在那里审查预检结果并对审批门采取行动,安全审计员通过其只读审计界面查询复合变更记录。两个界面共享同一 API 层,该层位于呈现层本身内,在任何请求到达底层模块之前执行认证、RBAC 和版本控制。
三个受众
应用团队通过 ServiceNow 表单提交请求。他们想知道服务何时准备好,以及如果失败了发生了什么。他们不应该需要打开 AWX 或 Nautobot。ServiceNow 是他们的呈现层;平台 API 是他们永远看不到的东西。
网络工程师在工作流进行中(第 7 章,步骤 3)收到了审批门通知。他们需要看到 24 台目标交换机的预检结果,批准或拒绝,并能够检查结果。他们的界面是自定义门户:比 ServiceNow 表单更详细,但仍然限定于他们团队的范围。
安全审计员三个月后到来,带着一个问题:谁请求了这个 VLAN,谁批准了它,运行的是哪个版本的部署工作流,受影响交换机的变更前后状态是什么?他们的界面是门户的审计视图:只读,没有触发任何东西的能力。
两个呈现界面
API 层是呈现层内的共享基础。ServiceNow 和自定义门户在任何请求到达底层模块之前,都通过它路由每个请求。它执行三种基于角色的令牌:应用团队的操作员令牌(读取自己的请求、提交新请求)、网络工程师的工程师令牌(读取其范围内的所有请求、批准或拒绝门控),以及审计员的只读令牌(查询整个平台的审计记录,无写入访问)。没有一个界面绕过它。
flowchart TD
subgraph Consumers
AT[Application Team]
NE[Network Engineer]
SA[Security Auditor]
end
subgraph PL[Presentation Layer]
SN[ServiceNow]
PORTAL[Custom Portal]
API[API Layer: Auth · RBAC · Versioning]
end
subgraph Blocks[Platform Blocks]
ORC[Orchestrator]
SOT[Source of Truth]
OBS[Observability]
end
AT --> SN
NE & SA --> PORTAL
SN & PORTAL --> API
API --> ORC & SOT & OBS
classDef presentation fill:#f0e6ff,stroke:#9b59b6,color:#4a235a
classDef api fill:#e8e8e8,stroke:#555,color:#111,font-weight:bold
classDef block fill:#f5f5f5,stroke:#999,color:#333
class SN,PORTAL presentation
class API api
class ORC,SOT,OBS block
步骤 1:ServiceNow 作为应用团队界面
应用团队填写一个 ServiceNow 表单:服务名称(app-payments)、子网大小(/24)、建筑(building-b)、请求团队和业务理由。提交时,ServiceNow 作为其自身工作流自动化的一部分直接调用平台 API 层。API 层根据 SoT 数据模型验证负载,认证 ServiceNow 使用的服务账户令牌,并将结构化请求转发给编排器。
如果验证失败(例如,请求的建筑与 SoT 中的任何站点不匹配,或子网大小与现有分配冲突),API 层立即返回结构化错误,在任何编排器工作流启动之前。ServiceNow 以清晰的失败原因更新工单:“building-c 在站点注册表中未找到"或"子网 /24 与 building-b 中现有分配 10.22.14.0/24 冲突。“应用团队在其工单中看到拒绝,可以纠正请求而不需要网络工程师介入。不会创建部分工作流状态,也不需要 Saga 回滚,因为工作流从未启动。
随着工作流进展,呈现层订阅编排器状态事件,并将其翻译成 ServiceNow 工单更新:“SoT 验证完成”,“预检运行中:24 台交换机”,“审批门:等待工程师签署”,“完成:24/24 台交换机已配置。“应用团队在不知道编排器、SoT 或 AWX 存在的情况下观看工单更新。
步骤 2:审批门界面
当工作流到达审批门时,编排器暂停并发出事件。呈现层接收它,识别负责 B 楼的网络工程师,并向其 Slack 渠道发送审批请求,附带到门控审查页面的直接链接。审查页面按交换机显示预检结果:哪些通过、哪些失败、哪些被跳过以及原因。工程师从门户批准或拒绝。操作被记录:谁批准、从哪个界面、什么时间、在哪个令牌下。
步骤 3:审计视图
三个月后,安全审计员查询呈现层 API:“给我展示 VLAN app-payments B 楼的完整变更记录。“只读审计端点从三个来源聚合:
- 编排器的执行记录(第 7 章,7.2.4 节):运行的工作流版本、每个步骤输入和输出、任何 Saga 补偿操作
- SoT 变更记录(第 4 章):VLAN 定义的变更前后状态
- 呈现层自己的授权日志:谁提交了请求、他们使用了哪个令牌、谁批准了门控以及何时
响应是一个结构化文档,审计员可以附加到变更管理记录上。三个底层模块都没有被设计为独立产生这个复合记录,呈现层在审计员的只读令牌下从它们各自的 API 中组装了它。
这展示了什么
来自第 7 章的同一个十步工作流,通过两个呈现界面服务了三种不同受众,这些受众都不需要了解底层平台。ServiceNow 作为自己的呈现界面服务于更广泛的组织:应用团队通过他们每天已经使用的工具追踪请求,没有意识到背后的 AWX、Nautobot 或编排器。自定义门户服务于工程和合规受众:网络工程师审查了范围化到他们团队请求的干净审批界面,审计员通过单一只读视图查询了从三个模块组装的复合变更记录。同一个 API 层为两个界面执行访问模型,使平台变得可访问而不使其可见。
8.4. 总结#
Presentation (Layer) 层是第 2 部分的最后一个构建块,也是最可能被视为事后想法的一个。其下面的模块做实质性工作:保存意图、应用变更、验证结果、协调工作流。呈现层什么都不产生。但没有它,平台只对构建它的人可访问,而其他所有受众都依赖于人类中间人。
API 层是基础。在 API 边界处(而不是每个工具)执行认证和授权,是将可访问的自动化与危险的自动化区分开来的东西。版本控制和稳定合同是将平台与在每次更新时破坏调用者的原型区分开来的东西。Model Context Protocol (MCP) 接口将相同的访问模型扩展到基于 Large Language Model (LLM) 的智能体,使平台对第 7 章介绍的智能体编排模式可用,并在第 17 章中进一步发展。
客户端界面是同一底层 API 的不同形态。带有渐进式披露的 GUI 门户服务于需要请求和追踪自动化而不了解平台的非工程师。CLI 服务于需要速度、可脚本化和 CI/CD 集成的操作员。ChatOps 和移动界面服务于审批流和事件查询。关于构建哪些界面的决策应该遵循深思熟虑的序列:从工程师受众的内置模块 UI 开始,当非工程师需要请求自动化时与 ITSM 集成,只有当 ITSM 证明不足时才构建自定义门户。
集成和通知关闭了第 7 章的异步响应合同打开的循环。编排器产生工作流结果;呈现层通过他们已经使用的渠道将其传递给触发操作的受众。双向 ITSM 同步、Webhook 回调和推送通知不是便利功能,而是使自动化对依赖它的人可见的东西。
园区场景在实践中展示了这一点:一个工作流、三个受众、两个呈现界面。ServiceNow 作为自己的呈现界面服务于更广泛的组织,直接调用平台 API,并通过熟悉的工单更新展示状态。自定义门户服务于工程和合规受众:网络工程师审查了范围化到他们团队请求的干净审批界面,审计员通过从编排器、SoT 和呈现层自己的授权日志中组装的复合变更记录的单一只读视图进行查询。同一 API 层为两者执行访问模型,平台不再是不可见的。
呈现层就位后,第 2 部分已经涵盖了 NAF 框架的所有七个构建块。下一章转向所有这些自动化最终作用于的那个模块:网络本身,在第 9 章中介绍。
💬 Found something to improve? Send feedback for this chapter