产品页面说它有 API,而集成会议在第二个问题上就卡住了。哪个操作、作用于哪个对象、由谁调用、什么算成功?在比较产品之前先回答这四个问题,通常就能刷掉一半候选者。它还能把剩下的比较变成测试可以裁决的事情。

把「有 API」换成一个具体操作

API 是传输方式,不是能力。REST 端点、本地套接字和命令行封装都可以叫 API,但它们提供的操作并不等价。

在看文档之前,先把这个操作写成一句话。

启动本地连接是面向用户的客户端动作。下发设备配置文件是背后有资产清单的供给动作。停用某个用户的访问是有审计痕迹的管理动作。这三者通常位于不同组件、由不同团队拥有、权限也不同。

让契约可测试的四个字段

为每个操作填写四个字段:对象、动作、调用方和成功条件。少一个字段的契约只是一厢情愿。

整张工作表就是下面这张表:

FieldQuestionExample
ObjectWhat is being acted on?One enrolled device
ActionObserve, create, change, start, stop, or revoke?Revoke
CallerWhich identity calls it?Deployment service
SuccessWhat observable state proves it?Future sign-in denied

成功条件正是人们会跳过的那一项,而它决定了集成是否真的可用。保存了设置不等于隧道已建立,账号被停用也不等于会话已结束。

如果两个操作需要不同的调用方,那它们就是两个集成。把它们塞进同一个服务账号,通常意味着授予的权限超过任何一方所需。

让接口对上它真正所属的层次

OpenVPN 社区版的管理接口通过 TCP 或 Unix 套接字与守护进程通信。它的命令包括状态观测和向守护进程发送信号。

所以它是守护进程的控制通道,而不是托管的订阅 API 或用户注册服务。仔细阅读它的文档,可以避免你在一个并不拥有该对象的层次上做集成。

文档也说明该协议本身不带加密。任何能访问套接字的人都能控制守护进程,所以要把它当作敏感控制面,而不是指标流。把它绑定到 loopback 或 Unix 套接字;如果确有远程调用方,就放在受限的安排之后。为了方便把它暴露到互联网,会把控制通道变成事故。

明确规定调用之后的行为

受理不等于完成。守护进程可能在隧道建立之前就返回,所以要等待文档中说明的完成或失败事件,并把它与发出的请求对应起来。

要决定响应丢失时调用方怎么做。盲目重发创建或重连请求,和检查第一个请求是否已经生效,是两回事。

撤销访问至少是三种不同的动作:阻止未来登录、终止活动会话、吊销凭据。按策略真正需要的去申请,并在契约里写清哪个是哪个。没有证据,就不要把一次成功的账号更新说成已完全吊销。在事故中时间紧迫,这个区别很重要。

用试点验证契约

小而获准的试点应覆盖成功、拒绝、中断和重试,然后再验证本应被允许或拒绝的应用操作。

对守护进程级接口,用两条命令分别演练观测和信号:

echo state | nc -w 2 127.0.0.1 7505
echo signal SIGTERM | nc -w 2 127.0.0.1 7505

只授予操作所需的权限。让密钥远离日常日志,同时记录足够多的私有细节,能说明影响了哪个目标、结果如何。

写下控制 API 本身不可用时的恢复路径。选那个拥有对象及其生命周期的接口;产品页面上的自动化宣称不能替代它。

相关文章