- OpenTofu 内部机制
- 提供程序注册表协议
提供程序注册表协议
提供程序注册表协议是 OpenTofu CLI 用于发现可安装提供程序的元数据以及查找所选提供程序的发行版软件包的协议。
此协议的主要实现是位于 registry.opentofu.org
的公共 OpenTofu 注册表。通过编写和部署您自己的协议实现,您可以创建一个单独的源注册表来分发您自己的提供程序,作为在公共 OpenTofu 注册表上发布它们的替代方案。
此页面描述了提供程序注册表协议,该协议用于查找可安装的提供程序。它不描述提供程序插件本身在运行时实现以服务来自 OpenTofu CLI 的请求的 API。有关提供程序 API 的更多信息,请参阅 OpenTofu SDK 文档。
提供程序地址
每个 OpenTofu 提供程序都关联一个地址,该地址在 OpenTofu 中唯一标识它。提供程序地址具有语法 hostname/namespace/type
,其中
hostname
是提供程序被认为源自的注册表主机,也是 OpenTofu 将查找有关提供程序的信息的默认位置 除非在 CLI 配置中被覆盖。namespace
是命名空间的名称,在特定主机上唯一,可以包含一个或多个以某种方式相关的提供程序。在公共 OpenTofu 注册表中,“命名空间”表示打包和分发提供程序的组织。type
是提供程序类型,例如“azurerm”、“aws”、“google”、“dns”等。提供程序类型在特定主机和命名空间内是唯一的。
提供程序地址的 hostname/
部分(包括其斜杠分隔符)是可选的,如果省略,则默认为 registry.opentofu.org/
。
例如
hashicorp/aws
是registry.opentofu.org/hashicorp/aws
的简写,它是 HashiCorp 发布的官方 AWS 提供程序。example/foo
是registry.opentofu.org/example/foo
的简写,它是发布在公共 OpenTofu 注册表上的假设第三方提供程序。example.com/bar/baz
是发布在example.com
上的第三方提供程序注册表上的假设第三方提供程序。
如果您只想与所有 OpenTofu 用户共享您开发的提供程序,请考虑将其发布到公共 OpenTofu 注册表,这将使您的提供程序可被发现。只有当您希望发布地址包含您控制下的不同主机的提供程序时,才需要实现此提供程序注册表协议。
OpenTofu 在内部使用完整地址(在规范化为始终包含主机名后)作为其提供程序的全局标识符,因此请注意,将 examplecorp/azurerm
提供程序重新上传到另一个命名空间或发布到不同的主机名将导致 OpenTofu 将其视为一个完全独立的提供程序,无法被声明对 examplecorp/azurerm
存在依赖关系的模块使用。如果您的目标是为现有提供程序创建备用本地分发源(即提供程序的镜像),请改为参考 提供程序安装方法配置。
提供程序版本
每个不同的提供程序地址都关联一组版本,每个版本都有一个关联的版本号。OpenTofu 假设版本号遵循 语义版本 2.0 约定,提供程序的架构和行为根据 OpenTofu 的最终用户的角度记录,作为“公共 API”。
OpenTofu 将特定提供程序地址的所有可用版本视为相同的提供程序。每个 OpenTofu 配置仅选择每个提供程序的一个版本在整个配置中使用,因此出于版本选择的目的,将考虑所有模块中的版本约束。
服务发现
提供程序协议以 OpenTofu CLI 使用OpenTofu 的远程服务发现协议开始,其中提供程序地址中的主机名充当“面向用户的 Hostname”。
提供程序注册表协议的服务标识符为 providers.v1
。其关联的字符串值为后续部分中定义的相对 URL 的基本 URL。
例如,仅实现提供程序注册表协议的主机服务发现文档可能包含以下内容
{
"providers.v1": "/tofu/providers/v1/"
}
如果给定的 URL 是相对 URL,则 OpenTofu 将将其解释为相对于发现文档本身。特定的提供程序注册表协议端点定义为相对于给定基本 URL 的 URL,因此指定的基 URL 通常应以斜杠结尾,以确保这些相对路径按预期解析。
以下部分描述了提供程序注册表必须实现的各种操作,才能与 OpenTofu CLI 的提供程序安装程序兼容。指示的 URL 均相对于服务发现产生的 URL,如上所述。我们使用提供程序注册表的假设 URL,假设调用者已对假设的 registry.example.io
执行了服务发现以了解基本 URL。
URL 使用以下约定显示:以冒号 :
为前缀的路径部分是动态选择值的占位符,而所有其他路径部分都是文字。例如,在 :namespace/:type/versions
中,前两个路径部分是占位符,而第三个是文字字符串“versions”。
列出可用版本
此操作确定当前可用于特定提供程序的哪些版本。
方法 | 路径 | 生成 |
---|---|---|
GET | :namespace/:type/versions | application/json |
参数
namespace
(必填):请求的提供程序地址的命名空间部分。type
(必填):请求的提供程序地址的类型部分。
示例请求
curl 'https://registry.opentofu.org/v1/providers/examplecorp/random/versions'
示例响应
{
"versions": [
{
"version": "2.0.0",
"protocols": ["4.0", "5.1"],
"platforms": [
{"os": "darwin", "arch": "amd64"},
{"os": "linux", "arch": "amd64"},
{"os": "linux", "arch": "arm"},
{"os": "windows", "arch": "amd64"}
]
},
{
"version": "2.0.1",
"protocols": ["5.2"],
"platforms": [
{"os": "darwin", "arch": "amd64"},
{"os": "linux", "arch": "amd64"},
{"os": "linux", "arch": "arm"},
{"os": "windows", "arch": "amd64"}
]
}
]
}
响应属性
成功的结果是一个 JSON 对象,包含单个属性 versions
。versions
是一个对象数组,每个对象描述一个可用版本,并具有以下属性
-
version
(必填):此对象描述的版本号,使用语义版本控制字符串表示法。version
在响应中的所有对象中必须唯一。 -
protocols
(推荐):此版本支持的 OpenTofu 提供程序 API 版本数组,每个版本都以MAJOR.MINOR
格式给出,其中每个主版本仅出现一次,并且给定的次版本是支持的最高次版本。例如,5.1
表示提供程序同时支持协议5.0
和协议5.1
。OpenTofu 使用此信息(如果可用)为用户提供有关升级或降级其特定提供程序版本的提示,以使其与他们当前的 OpenTofu 版本一起使用,如果他们当前选择的版本不兼容。
对于大多数提供程序,支持哪些 API 版本取决于它们构建所依据的 Terraform SDK 版本。有关更多信息,请参阅 Terraform SDK 文档。
-
platforms
(推荐):一个对象数组,描述此版本可用的软件包的平台。OpenTofu 可能会使用此信息(如果可用)为用户提供有关升级或降级其特定提供程序版本的提示,以使其与他们当前的平台兼容。
platforms
对象具有属性os
和arch
,其值与查找提供程序软件包响应中同名属性的值匹配。
返回 404 Not Found
以指示注册表没有具有给定命名空间和类型的提供程序。
查找提供程序软件包
此操作返回特定提供程序的特定版本的特定操作系统和体系结构的发布软件包的下载 URL 和相关元数据。
OpenTofu CLI 在选择与配置的版本约束匹配的最新可用版本后,使用此操作来查找包含插件本身的 zip 存档。
方法 | 路径 | 生成 |
---|---|---|
GET | :namespace/:type/:version/download/:os/:arch | application/json |
参数
namespace
(必填):请求的提供程序地址的命名空间部分。type
(必填):请求的提供程序地址的类型部分。version
(必填):选择下载的版本。这将与之前对列出可用版本的调用返回的版本字符串之一完全匹配。os
(必填):识别返回的软件包应与其兼容的操作系统的关键字,例如“linux”或“darwin”。arch
(必填):识别返回的软件包应与其兼容的 CPU 体系结构的关键字,例如“amd64”或“arm”。
示例请求
curl 'https://registry.opentofu.org/v1/providers/examplecorp/random/2.0.0/download/linux/amd64'
示例响应
{
"protocols": ["4.0", "5.1"],
"os": "linux",
"arch": "amd64",
"filename": "terraform-provider-random_2.0.0_linux_amd64.zip",
"download_url": "https://releases.example.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_linux_amd64.zip",
"shasums_url": "https://releases.example.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_SHA256SUMS",
"shasums_signature_url": "https://releases.example.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_SHA256SUMS.sig",
"shasum": "5f9c7aa76b7c34d722fc9123208e26b22d60440cb47150dd04733b9b94f4541a",
"signing_keys": {
"gpg_public_keys": [
{
"key_id": "51852D87348FFC4C",
"ascii_armor": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n\nmQENBFMORM0BCADBRyKO1MhCirazOSVwcfTr1xUxjPvfxD3hjUwHtjsOy/bT6p9f\nW2mRPfwnq2JB5As+paL3UGDsSRDnK9KAxQb0NNF4+eVhr/EJ18s3wwXXDMjpIifq\nfIm2WyH3G+aRLTLPIpscUNKDyxFOUbsmgXAmJ46Re1fn8uKxKRHbfa39aeuEYWFA\n3drdL1WoUngvED7f+RnKBK2G6ZEpO+LDovQk19xGjiMTtPJrjMjZJ3QXqPvx5wca\nKSZLr4lMTuoTI/ZXyZy5bD4tShiZz6KcyX27cD70q2iRcEZ0poLKHyEIDAi3TM5k\nSwbbWBFd5RNPOR0qzrb/0p9ksKK48IIfH2FvABEBAAG0K0hhc2hpQ29ycCBTZWN1\ncml0eSA8c2VjdXJpdHlAaGFzaGljb3JwLmNvbT6JATgEEwECACIFAlMORM0CGwMG\nCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEFGFLYc0j/xMyWIIAIPhcVqiQ59n\nJc07gjUX0SWBJAxEG1lKxfzS4Xp+57h2xxTpdotGQ1fZwsihaIqow337YHQI3q0i\nSqV534Ms+j/tU7X8sq11xFJIeEVG8PASRCwmryUwghFKPlHETQ8jJ+Y8+1asRydi\npsP3B/5Mjhqv/uOK+Vy3zAyIpyDOMtIpOVfjSpCplVRdtSTFWBu9Em7j5I2HMn1w\nsJZnJgXKpybpibGiiTtmnFLOwibmprSu04rsnP4ncdC2XRD4wIjoyA+4PKgX3sCO\nklEzKryWYBmLkJOMDdo52LttP3279s7XrkLEE7ia0fXa2c12EQ0f0DQ1tGUvyVEW\nWmJVccm5bq25AQ0EUw5EzQEIANaPUY04/g7AmYkOMjaCZ6iTp9hB5Rsj/4ee/ln9\nwArzRO9+3eejLWh53FoN1rO+su7tiXJA5YAzVy6tuolrqjM8DBztPxdLBbEi4V+j\n2tK0dATdBQBHEh3OJApO2UBtcjaZBT31zrG9K55D+CrcgIVEHAKY8Cb4kLBkb5wM\nskn+DrASKU0BNIV1qRsxfiUdQHZfSqtp004nrql1lbFMLFEuiY8FZrkkQ9qduixo\nmTT6f34/oiY+Jam3zCK7RDN/OjuWheIPGj/Qbx9JuNiwgX6yRj7OE1tjUx6d8g9y\n0H1fmLJbb3WZZbuuGFnK6qrE3bGeY8+AWaJAZ37wpWh1p0cAEQEAAYkBHwQYAQIA\nCQUCUw5EzQIbDAAKCRBRhS2HNI/8TJntCAClU7TOO/X053eKF1jqNW4A1qpxctVc\nz8eTcY8Om5O4f6a/rfxfNFKn9Qyja/OG1xWNobETy7MiMXYjaa8uUx5iFy6kMVaP\n0BXJ59NLZjMARGw6lVTYDTIvzqqqwLxgliSDfSnqUhubGwvykANPO+93BBx89MRG\nunNoYGXtPlhNFrAsB1VR8+EyKLv2HQtGCPSFBhrjuzH3gxGibNDDdFQLxxuJWepJ\nEK1UbTS4ms0NgZ2Uknqn1WRU1Ki7rE4sTy68iZtWpKQXZEJa0IGnuI2sSINGcXCJ\noEIgXTMyCILo34Fa/C6VCm2WBgz9zZO8/rHIiQm1J5zqz0DrDwKBUM9C\n=LYpS\n-----END PGP PUBLIC KEY BLOCK-----",
"trust_signature": "",
"source": "ExampleCorp",
"source_url": "https://www.examplecorp.com/security.html"
}
]
}
}
响应属性
成功的结果是一个 JSON 对象,具有以下属性
-
protocols
(必填):提供程序支持的 OpenTofu 提供程序 API 版本数组,格式与列出可用版本相同。虽然此属性在列出可用选项时是可选的,但它对于描述单个提供程序软件包是必需的,以便 OpenTofu CLI 可以避免下载与其不兼容的软件包。
-
os
(必填):这必须回显请求中的os
参数。 -
arch
(必填):这必须回显请求中的arch
参数。 -
filename
(必填):此提供程序的 zip 存档的文件名,如“shasums”文档中记录的那样,以便 OpenTofu CLI 可以确定应为此特定软件包使用哪些给定的校验和。 -
download_url
(必填):OpenTofu 可以从中检索提供程序的 zip 存档的 URL。如果这是一个相对 URL,则它将相对于返回包含 JSON 对象的 URL 解析。 -
shasums_url
(必填):OpenTofu 可以从中检索文本文档的 URL,该文档记录此软件包以及可能在其他平台上相同提供程序版本的其他软件包的预期 SHA256 校验和。指示的文档必须采用许多 Unix 系统上可用的
sha256
命令生成的格式,其中一个条目记录filename
属性中给出的相同文件名(区分大小写)。 -
shasums_signature_url
(必填):OpenTofu 可以从中检索二进制分离 GPG 签名的 URL,该签名针对shasums_url
中的文档进行签名,并由signing_keys
属性中指示的密钥之一签名。 -
shasum
(必填):此提供程序的 zip 存档的 SHA256 校验和,如 shasums 文档中记录的那样。 -
signing_keys
(必填):一个对象,描述此提供程序软件包的签名密钥,其中一个密钥必须用于生成shasums_signature_url
中的签名。该对象具有以下嵌套属性-
gpg_public_keys
(必填):一个对象数组,每个对象描述一个允许对此提供程序版本的校验和进行签名的 GPG 签名密钥。必须包含至少一个元素,表示生成shasums_signature_url
中签名的密钥。这些对象具有以下嵌套属性-
key_id
(必填):此 GPG 密钥的大写十六进制格式 ID -
ascii_armor
(必填):与此 GPG 密钥关联的公钥的“ascii-armor”编码。
-
-
返回 404 Not Found
以指示给定的提供程序版本在请求的操作系统和/或体系结构中不可用。OpenTofu CLI 仅尝试下载它之前在对列出可用版本的响应中看到的版本。