feat: serve local terraform repos as a provider registry
Local terraform repos already spoke the network mirror protocol, which needs
per-consumer .terraformrc config. This adds the provider registry protocol so
`terraform init` installs from a bare source address
(artifactapi.k8s.../{repo}/{type}) with no client setup.
- serve /.well-known/terraform.json service discovery and the providers.v1
versions/download endpoints under /terraform/v1/providers
- map the Terraform namespace to the artifactapi repo name and locate the
provider by type; download_url points back at the existing local file path
- generate SHA256SUMS per version and sign it with a GPG key loaded from
TF_SIGNING_KEY_PATH; advertise the public key + key id in the download
response. No key configured -> registry stays disabled (endpoints 404)
- new internal/tfsign (key loading + detached signing) and
internal/api/terraform (registry handler); export ParseProviderZip for reuse
- add TF_SIGNING_KEY_PATH/PASSPHRASE and TF_PROVIDER_PROTOCOLS config
- unit test signing + verification; dockerised test of the full flow incl.
signature verification against the advertised key
Also anchor the terraform/ gitignore to the repo root so it stops swallowing
internal/api/terraform and internal/provider/terraform test files (the latter
had gone silently untracked).
This commit is contained in:
@@ -26,6 +26,27 @@ var providerZipRe = regexp.MustCompile(
|
||||
|
||||
var semverRe = regexp.MustCompile(`^[0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9.]+)?$`)
|
||||
|
||||
// ParsedProviderZip describes a terraform-provider-{type}_{version}_{os}_{arch}.zip
|
||||
// filename. Ok is false when the name doesn't match that convention.
|
||||
type ParsedProviderZip struct {
|
||||
Type string
|
||||
Version string
|
||||
OS string
|
||||
Arch string
|
||||
Ok bool
|
||||
}
|
||||
|
||||
// ParseProviderZip extracts the type, version and platform from a provider zip
|
||||
// filename (the base name, not a full path). It's the canonical parser shared by
|
||||
// the network-mirror index and the provider registry handler.
|
||||
func ParseProviderZip(filename string) ParsedProviderZip {
|
||||
m := providerZipRe.FindStringSubmatch(filename)
|
||||
if m == nil {
|
||||
return ParsedProviderZip{}
|
||||
}
|
||||
return ParsedProviderZip{Type: m[1], Version: m[2], OS: m[3], Arch: m[4], Ok: true}
|
||||
}
|
||||
|
||||
type Provider struct{}
|
||||
|
||||
func (p *Provider) Type() models.PackageType { return models.PackageTerraform }
|
||||
|
||||
Reference in New Issue
Block a user