Closed
Description
Use Case
Downstream in Terraform Provider SDKs such as terraform-plugin-go, terraform-plugin-framework, and terraform-plugin-sdk, it would be great if we could verify provider developer defined strings that should only contain a full provider address, e.g. "registry.terraform.io/hashicorp/example"
. We want to ensure a full provider address is submitted as this value can eventually wind up in Terraform reattach configurations.
This module currently provides the ParseAndInferProviderSourceString()
and ParseRawProviderSourceString()
functions, however they allow a few things we don't desire:
- Missing hostname
- Missing namespace
- Namespace being
-
(which is valid for legacy reasons when the hostname isregistry.terraform.io
, but not something we want to allow for this use case)
Attempted Solutions
Manual logic:
// Validate a given provider address. This is only used for the Address field
// to preserve backwards compatibility for the Name field.
//
// This logic is manually implemented over importing
// github.com/hashicorp/terraform-registry-address as its functionality such as
// ParseAndInferProviderSourceString and ParseRawProviderSourceString allow
// shorter address formats, which would then require post-validation anyways.
func (opts ServeOpts) validateAddress(_ context.Context) error {
addressParts := strings.Split(opts.Address, "/")
formatErr := fmt.Errorf("expected hostname/namespace/type format, got: %s", opts.Address)
if len(addressParts) != 3 {
return formatErr
}
if addressParts[0] == "" || addressParts[1] == "" || addressParts[2] == "" {
return formatErr
}
return nil
}
Proposal
Implement a function in this Go module similar to the above, potentially with better validation. 😄 e.g.
func ValidateFullProviderAddress(in string) error {
addressParts := strings.Split(in, "/")
formatErr := fmt.Errorf("expected hostname/namespace/type format, got: %s", in)
if len(addressParts) != 3 {
return formatErr
}
provider := Provider{
Hostname: addressParts[0],
Namespace: addressParts[1],
Type: addressParts[2],
}
if provider.Hostname == "" || provider.Namespace == "" || provider.Type == "" {
return formatErr
}
if provider.Namespace == "-" {
return fmt.Errorf("expected defined namespace, the - namespace is reserved, got: %s", in)
}
return nil
}