github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/configs/provider_requirements.go (about)

     1  package configs
     2  
     3  import (
     4  	"fmt"
     5  
     6  	version "github.com/hashicorp/go-version"
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/hashicorp/terraform/addrs"
     9  )
    10  
    11  // RequiredProvider represents a declaration of a dependency on a particular
    12  // provider version without actually configuring that provider. This is used in
    13  // child modules that expect a provider to be passed in from their parent.
    14  //
    15  // TODO: "Source" is a placeholder for an attribute that is not yet supported.
    16  type RequiredProvider struct {
    17  	Name        string
    18  	Source      string // TODO
    19  	Requirement VersionConstraint
    20  }
    21  
    22  // ProviderRequirements represents merged provider version constraints.
    23  // VersionConstraints come from terraform.require_providers blocks and provider
    24  // blocks.
    25  type ProviderRequirements struct {
    26  	Type               addrs.Provider
    27  	VersionConstraints []VersionConstraint
    28  }
    29  
    30  func decodeRequiredProvidersBlock(block *hcl.Block) ([]*RequiredProvider, hcl.Diagnostics) {
    31  	attrs, diags := block.Body.JustAttributes()
    32  	var reqs []*RequiredProvider
    33  	for name, attr := range attrs {
    34  		expr, err := attr.Expr.Value(nil)
    35  		if err != nil {
    36  			diags = append(diags, err...)
    37  		}
    38  
    39  		rp := &RequiredProvider{
    40  			Name: name,
    41  		}
    42  
    43  		switch {
    44  		case expr.Type().IsPrimitiveType():
    45  			vc, reqDiags := decodeVersionConstraint(attr)
    46  			diags = append(diags, reqDiags...)
    47  			rp.Requirement = vc
    48  
    49  		case expr.Type().IsObjectType():
    50  			if expr.Type().HasAttribute("version") {
    51  				vc := VersionConstraint{
    52  					DeclRange: attr.Range,
    53  				}
    54  				constraintStr := expr.GetAttr("version").AsString()
    55  				constraints, err := version.NewConstraint(constraintStr)
    56  				if err != nil {
    57  					// NewConstraint doesn't return user-friendly errors, so we'll just
    58  					// ignore the provided error and produce our own generic one.
    59  					diags = append(diags, &hcl.Diagnostic{
    60  						Severity: hcl.DiagError,
    61  						Summary:  "Invalid version constraint",
    62  						Detail:   "This string does not use correct version constraint syntax.",
    63  						Subject:  attr.Expr.Range().Ptr(),
    64  					})
    65  				} else {
    66  					vc.Required = constraints
    67  					rp.Requirement = vc
    68  				}
    69  			}
    70  			if expr.Type().HasAttribute("source") {
    71  				diags = append(diags, &hcl.Diagnostic{
    72  					Severity: hcl.DiagWarning,
    73  					Summary:  "Provider source not supported in Terraform v0.12",
    74  					Detail:   fmt.Sprintf("A source was declared for provider %s. Terraform v0.12 does not support the provider source attribute. It will be ignored.", name),
    75  					Subject:  attr.Expr.Range().Ptr(),
    76  				})
    77  			}
    78  		default:
    79  			// should not happen
    80  			diags = append(diags, &hcl.Diagnostic{
    81  				Severity: hcl.DiagError,
    82  				Summary:  "Invalid provider_requirements syntax",
    83  				Detail:   "provider_requirements entries must be strings or objects.",
    84  				Subject:  attr.Expr.Range().Ptr(),
    85  			})
    86  			reqs = append(reqs, &RequiredProvider{Name: name})
    87  			return reqs, diags
    88  		}
    89  		reqs = append(reqs, rp)
    90  	}
    91  	return reqs, diags
    92  }