Skip to content

Functionality for Verifying Full Provider Addresses (hostname/namespace/type) #10

Closed
@bflad

Description

@bflad

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 is registry.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
}

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions