LabHub
学习 学习路径 课程

CAPA — Argo 项目认证助理

一个订单、两个工作流:事件故障实验室

在 LabHub 中继续学习

目标

用真实 event、Workflow 和订单 ledger 验证 filter、权限与 duplicate handling 的边界。

为什么重要

HTTP 200 不代表业务完成。此 VM 提供真实 k3s、Argo Events 1.9.11、Workflows 4.1.3 和本地 SQLite ledger。你需要修正错误 Sensor 的 field,并比较 helper 发送的对照 input 所产生的真实执行与业务效果。 每一步使用独立 Sensor 和 port,因此第 2~8 步可以跳过前一步直接开始。第 9 步的准备只补齐未修改的前序材料,不会覆盖你的修改与报告。

步骤

  1. 用 kubectl 读取 EventSource lesson、EventBus default 和 Role sensor-submit。在 /root/capa-events/inventory.json 中记录 namespace=argo-events、eventsource=lesson、eventbus=default、submit_account=sensor-submit、workflow_account=workflow-runner、http_is_completion=false。HTTP 接收与 Workflow 完成是不同边界。
  2. 在 /root/capa-events/path.yaml 中,只把第一个 data filter 的 path 从 body.event.kind 改为 body.kind,然后运行 helper 的 run path。helper 会向错误 baseline 与修正版发送 flat、nested body。baseline 只能为 nested 创建真实 Workflow,修正版则必须为两者都创建。
  3. 在 /root/capa-events/regex.yaml 中,只把第一个 data filter 的 value 改为 ["^order[.]created$"],然后运行 run regex。pre-orderXcreated-tail 在 baseline 中会被接受,修改后必须拒绝;order.created 对照组仍须执行。
  4. 保留 /root/capa-events/types.yaml 的现有 data filter,并在 filters.script 中加入 return type(event.body.enabled) == "boolean" and event.body.enabled == true。用 run types 比较 false、字符串 true、数字 1、缺少 field、boolean true;修改后只有最后一个 input 应执行。
  5. 只把 /root/capa-events/logic.yaml 的 filters.dataLogicalOperator 从 or 改为 and,然后运行 run logic。enabled=true 的 order.deleted 修改后必须拒绝,order.created 必须执行;保留两个 filter 和其他设置。
  6. 把 /root/capa-events/repair-binding.yaml 的 roleRef.name 改为 sensor-submit。保留 name sensor-repair、namespace argo-events、kind Role、apiGroup rbac.authorization.k8s.io,以及 subjects 中 argo-events 的唯一 ServiceAccount sensor-repair。保持 rbac.yaml 不变并运行 run rbac。Role 只保留 Workflow create,不要增加 binding。helper 会保留无权限 baseline 的真实 forbidden,并确认修复账户的新请求。
  7. 保持 /root/capa-events/duplicate.yaml 不变并运行 run duplicate。确认两个相同 HTTP body 产生不同 arrival label 和两个 Workflow UID。每个 Workflow 的 order-id 必须是相同业务 key,真实 Pod 必须成功结束。这是两次 HTTP request,不是 broker redelivery 实验。
  8. 在 /root/capa-events/ledger.yaml 的 Workflow container args 最后一个 URL 中,只把 /naive 改为 /safe,然后运行 run ledger。保留 address、port、1250 amount 与业务 key 传递。baseline 应产生 2 条 ledger effect,修正版应产生 1 条;两个 Workflow 都成功,修正版结果为 applied 与 duplicate。helper 的相同 key、不同 amount 请求必须返回 409。
  9. 完成前述实验后运行 run boundaries。比较 ledger API 的 16 个 concurrent request、未读取 response 的 request、ledger service 重启后相同 key 的再次请求,以及 5 种错误 amount。在 /root/capa-events/report.json 中,duplicate_attempt 与 boundary_attempt 写各自当前执行 ID,workflow_uids 按升序写 duplicate 的两个真实 UID。记录 http_requests=2、workflow_executions=2、safe_effects=1、concurrent_requests=16、restart_preserved=true、broker_redelivery_proven=false、external_exactly_once_proven=false。ledger 重启不是 VM 或 broker 重启。

参考

识别接收与业务完成的边界

用 kubectl 读取 EventSource lesson、EventBus default 和 Role sensor-submit。在 /root/capa-events/inventory.json 中记录 namespace=argo-events、eventsource=lesson、eventbus=default、submit_account=sensor-submit、workflow_account=workflow-runner、http_is_completion=false。HTTP 接收与 Workflow 完成是不同边界。

使用 kubectl -n argo-events get eventsource lesson -o yaml 和 get role sensor-submit -o yaml 读取真实 object。

用正常对照组识别不存在的 JSON path

在 /root/capa-events/path.yaml 中,只把第一个 data filter 的 path 从 body.event.kind 改为 body.kind,然后运行 helper 的 run path。helper 会向错误 baseline 与修正版发送 flat、nested body。baseline 只能为 nested 创建真实 Workflow,修正版则必须为两者都创建。

区分 HTTP body 与 Argo event envelope 中的 body。不要只看未执行,还要确认 nested 对照组成功。

阻止 regex 过度匹配

在 /root/capa-events/regex.yaml 中,只把第一个 data filter 的 value 改为 ["^order[.]created$"],然后运行 run regex。pre-orderXcreated-tail 在 baseline 中会被接受,修改后必须拒绝;order.created 对照组仍须执行。

点号默认匹配任意字符;没有 anchor 时,substring 也可能匹配。

区分类真值与真正的 JSON boolean

保留 /root/capa-events/types.yaml 的现有 data filter,并在 filters.script 中加入 return type(event.body.enabled) == "boolean" and event.body.enabled == true。用 run types 比较 false、字符串 true、数字 1、缺少 field、boolean true;修改后只有最后一个 input 应执行。

不要仅凭 type: bool 的转换结果推断原始 type;同时使用 Lua 的 type 与 value comparison。

拒绝只满足一个条件的请求

只把 /root/capa-events/logic.yaml 的 filters.dataLogicalOperator 从 or 改为 and,然后运行 run logic。enabled=true 的 order.deleted 修改后必须拒绝,order.created 必须执行;保留两个 filter 和其他设置。

即使每个 condition 正确,组合 operator 不同,allow set 也会改变。

以最小权限修复真实 forbidden

把 /root/capa-events/repair-binding.yaml 的 roleRef.name 改为 sensor-submit。保留 name sensor-repair、namespace argo-events、kind Role、apiGroup rbac.authorization.k8s.io,以及 subjects 中 argo-events 的唯一 ServiceAccount sensor-repair。保持 rbac.yaml 不变并运行 run rbac。Role 只保留 Workflow create,不要增加 binding。helper 会保留无权限 baseline 的真实 forbidden,并确认修复账户的新请求。

创建 Workflow 的 Sensor 账户与 Workflow 的执行账户不同。不要授予 administrator,应连接现有最小 Role。

追踪同一订单的两个不同执行

保持 /root/capa-events/duplicate.yaml 不变并运行 run duplicate。确认两个相同 HTTP body 产生不同 arrival label 和两个 Workflow UID。每个 Workflow 的 order-id 必须是相同业务 key,真实 Pod 必须成功结束。这是两次 HTTP request,不是 broker redelivery 实验。

在 helper result path 中比较 events 与 after.executions。业务 key 相同,arrival ID 与执行 UID 仍可不同。

把两次执行限制为一次业务 effect

在 /root/capa-events/ledger.yaml 的 Workflow container args 最后一个 URL 中,只把 /naive 改为 /safe,然后运行 run ledger。保留 address、port、1250 amount 与业务 key 传递。baseline 应产生 2 条 ledger effect,修正版应产生 1 条;两个 Workflow 都成功,修正版结果为 applied 与 duplicate。helper 的相同 key、不同 amount 请求必须返回 409。

URL 位于 spec.triggers[0].template.k8s.source.resource.spec.templates[0].container.args。保存前先读取原 address。

报告 concurrent request、restart boundary 与未验证范围

完成前述实验后运行 run boundaries。比较 ledger API 的 16 个 concurrent request、未读取 response 的 request、ledger service 重启后相同 key 的再次请求,以及 5 种错误 amount。在 /root/capa-events/report.json 中,duplicate_attempt 与 boundary_attempt 写各自当前执行 ID,workflow_uids 按升序写 duplicate 的两个真实 UID。记录 http_requests=2、workflow_executions=2、safe_effects=1、concurrent_requests=16、restart_preserved=true、broker_redelivery_proven=false、external_exactly_once_proven=false。ledger 重启不是 VM 或 broker 重启。

读取 runtime.py status CASE 指向的 result.json 原文。观测尚未结束时不要创建新实验,应对同一 handle 使用 wait。