- OpenTofu 内部结构
- 提供商网络镜像协议
提供商网络镜像协议
提供商网络镜像协议是一个可选协议,您可以实施该协议以提供 Terraform 提供商的替代安装来源,无论其来源注册表是什么。
OpenTofu 仅在您在 CLI 配置的 provider_installation
块 中显式激活网络镜像时使用网络镜像。启用后,网络镜像可以提供属于任何注册表主机名的提供商,这使组织能够从内部服务器而不是从每个提供商的来源注册表提供他们打算使用 OpenTofu 提供商。
这不是打算作为 OpenTofu 提供商的来源注册表的主机应实施的协议。要提供一个来源注册表(其主机名随后将包含在其托管的提供商的源地址中),请改而实施 提供商注册表协议。
提供商地址
每个 OpenTofu 提供商都有一个关联的地址,该地址在 OpenTofu 中唯一标识它。提供商地址具有语法 hostname/namespace/type
,这在 提供商要求文档 中有更详细的说明。
默认情况下,提供商地址的 hostname
部分既用作其唯一标识符的一部分,也用作从中检索它的注册表的位置。但是,当您将 OpenTofu 配置为从网络镜像安装提供商时,hostname
仅用作标识符,不再用作安装来源。因此,提供商镜像可以从单个服务器提供属于各种不同提供商注册表主机名的提供商,包括来自 registry.opentofu.org
的公共 OpenTofu 注册表的提供商。
在本文档后面的相对 URL 模式中,占位符 :hostname
指的是所请求提供商的地址中的主机名,而不是提供商网络镜像部署到的主机名。
协议基本 URL
大多数 OpenTofu 本地服务使用 远程服务发现协议,以便端点的物理位置可以与标识符中使用的主机名分离。提供商网络镜像协议不使用服务发现间接,因为网络镜像位置只是一个物理位置,永远不会用作 OpenTofu 配置中依赖项的标识符的一部分。
相反,CLI 配置的提供商安装部分直接接受基本 URL。给定的 URL 必须使用 https:
方案,并且应以尾部斜杠结尾,以便单个操作端点的相对 URL 将在它下面解析。
provider_installation {
network_mirror {
url = "https://tofu.example.com/providers/"
}
}
OpenTofu 仅将基本 URL 用作解析操作端点 URL 的基准,因此它永远不会直接访问基本 URL。因此,如果需要,您可以在该 URL 上发布网络镜像的人类可读使用文档。
以下部分描述了提供商网络镜像服务器必须实施的各种操作才能与 OpenTofu CLI 的提供商安装程序兼容。如上所述,指示的 URL 均相对于给定的基本 URL。
URL 使用以下约定显示:以冒号 :
为前缀的路径部分是动态选择的值的占位符,而所有其他路径部分都是文字。例如,在 :hostname/:namespace/:type/index.json
中,前三个路径部分是占位符,而第三个部分是文字字符串“index.json”。
以下部分中的示例请求将假设上述 CLI 配置示例中的示例镜像基本 URL。
身份验证
如果 CLI 配置包含 凭据 用于网络镜像基本 URL 中给定的主机名,则 OpenTofu 将在它对下面描述的操作的请求中包含这些凭据。
如果给定的 URL 使用非标准端口号(除 443 外),则凭据必须与包含端口号的主机名相关联,例如 tofu.example.com:8443
。
OpenTofu 在检索其 URL 在下面“列出可用安装包”响应中给出的档案时不发送凭据。如果特定镜像认为分发包本身是敏感的,则它必须在元数据响应中使用加密安全的、特定于用户的、时间限制的 URL。这样做的方法超出了此协议文档的范围。
列出可用版本
此操作确定当前为特定提供商提供哪些版本。
方法 | 路径 | 生成 |
---|---|---|
GET | :hostname/:namespace/:type/index.json | application/json |
参数
hostname
(必需):所请求提供商地址中的主机名部分。namespace
(必需):所请求提供商地址中的命名空间部分。type
(必需):所请求提供商地址中的类型部分。
示例请求
curl 'https://tofu.example.com/providers/registry.tofu.io/hashicorp/random/index.json'
示例响应
{
"versions": {
"2.0.0": {},
"2.0.1": {}
}
}
响应属性
成功的返回值是一个包含单个属性 versions
的 JSON 对象,该属性必须是 JSON 对象。
versions
对象的每个属性名称代表一个可用的版本号。属性值必须是对象,但这些对象没有定义任何属性。我们建议保持这些对象为空,以确保向前兼容性。
返回 404 Not Found
表示镜像没有提供给定地址的提供商。
列出可用的安装包
此操作将返回提供商特定版本的发布包的下载 URL 和相关元数据。
每个发布包都与特定的操作系统和架构相关联。如果镜像用户只使用 OpenTofu 支持的目标平台的子集,则网络镜像可能只包含提供商版本的部分可用包。
OpenTofu CLI 在选择与配置的版本约束匹配的最新可用版本后,将使用此操作来查找包含插件本身的 zip 存档。
方法 | 路径 | 生成 |
---|---|---|
GET | :hostname/:namespace/:type/:version.json | application/json |
参数
hostname
(必需):所请求提供商地址中的主机名部分。namespace
(必需):所请求提供商地址中的命名空间部分。type
(必需):所请求提供商地址中的类型部分。version
(必填):要下载的版本。这将与之前调用 列出可用版本 返回的版本字符串之一完全匹配。
示例请求
curl 'https://tofu.example.com/providers/registry.tofu.io/hashicorp/random/2.0.0.json'
示例响应
{
"archives": {
"darwin_amd64": {
"url": "terraform-provider-random_2.0.0_darwin_amd64.zip",
"hashes": [
"h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs="
]
},
"linux_amd64": {
"url": "terraform-provider-random_2.0.0_linux_amd64.zip",
"hashes": [
"h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ="
]
}
}
}
响应属性
成功的返回值是一个包含名为 archives
的属性的 JSON 对象,该属性必须是 JSON 对象。
archives
对象的每个属性名称都是一个目标平台标识符,它由操作系统和架构连接在一起,中间用下划线 (_
) 分隔。
archives
对象中每个属性值本身都是一个嵌套对象,具有以下属性
-
url
(必填):一个字符串,指定 OpenTofu 应该从中下载包含请求的提供商插件版本的.zip
存档的 URL。OpenTofu 会根据返回当前 JSON 文档的 URL 解析 URL,因此上面的示例中只包含文件名会导致 OpenTofu 构造一个类似于以下的 URL:
代码块 https://tofu.example.com/providers/registry.opentofu.org/hashicorp/random/terraform-provider-random_2.0.0_darwin_amd64.zip
-
hashes
(可选):一个包含一个或多个存档哈希值的字符串的 JSON 数组。这些哈希值使用 OpenTofu 的提供商包哈希算法。目前,填充这些哈希值的最佳方法是使用后面的章节中描述的tofu providers mirror
命令来构建镜像的 JSON 索引,该命令将包含每个提供商的计算出的哈希值。如果响应包含至少一个哈希值,OpenTofu 将选择它认为最强的哈希算法,并验证下载的包是否与该哈希值匹配。如果响应不包含
hashes
属性,OpenTofu 将安装指定的存档,不进行验证。
OpenTofu CLI 只会尝试下载之前在响应 列出可用版本 中看到的版本。
提供商镜像作为静态网站
提供商镜像协议的设计初衷是,它可以在典型的静态网站托管服务上放置文件后进行实现。使用此策略时,将上面描述的 JSON 索引响应实现为 .json
文件,并将其放置在适当的嵌套子目录中,并确保系统配置为使用 application/json
媒体类型提供 .json
文件。
为方便起见,OpenTofu CLI 包含 tofu providers mirror
子命令,该命令将分析当前配置以获取其所需的提供商,从其源注册表下载这些提供商的包,并将它们放置到一个适合用作镜像的本地目录中。
tofu providers mirror
子命令还会生成 index.json
和特定版本的 .json
文件,这些文件放置在静态网站托管系统中后,可以生成与提供商镜像协议兼容的响应。
如果希望使用多个不同的 OpenTofu 配置来创建包含提供商的镜像,请依次在每个配置中运行 tofu providers mirror
,并每次都提供相同的输出目录。OpenTofu 随后将合并所有需求到一个 JSON 索引集中。