internal/depsfile: Introduce the concept of "non-lockable" providers
It doesn't make sense for a built-in provider to appear in a lock file because built-in providers have no version independent of the version of Terraform they are compiled into. We also exclude legacy providers here, because they were supported only as a transitional aid to enable the Terraform 0.13 upgrade process and are not intended for explicit selection. The provider installer will, once it's updated to understand dependency locking, use this concept to decide which subset of its selections to record in the dependency lock file for reference for future installation requests.
This commit is contained in:
parent
98e2e69abb
commit
773dd56b42
|
@ -1,6 +1,7 @@
|
|||
package depsfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
|
@ -52,7 +53,16 @@ func (l *Locks) Provider(addr addrs.Provider) *ProviderLock {
|
|||
// SetProvider returns the newly-created provider lock object, which
|
||||
// invalidates any ProviderLock object previously returned from Provider or
|
||||
// SetProvider for the given provider address.
|
||||
//
|
||||
// Only lockable providers can be passed to this method. If you pass a
|
||||
// non-lockable provider address then this function will panic. Use
|
||||
// function ProviderIsLockable to determine whether a particular provider
|
||||
// should participate in the version locking mechanism.
|
||||
func (l *Locks) SetProvider(addr addrs.Provider, version getproviders.Version, constraints getproviders.VersionConstraints, hashes map[getproviders.Platform][]string) *ProviderLock {
|
||||
if !ProviderIsLockable(addr) {
|
||||
panic(fmt.Sprintf("Locks.SetProvider with non-lockable provider %s", addr))
|
||||
}
|
||||
|
||||
// Normalize the hash lists into a consistent order.
|
||||
for _, slice := range hashes {
|
||||
sort.Strings(slice)
|
||||
|
@ -68,6 +78,15 @@ func (l *Locks) SetProvider(addr addrs.Provider, version getproviders.Version, c
|
|||
return new
|
||||
}
|
||||
|
||||
// ProviderIsLockable returns true if the given provider is eligible for
|
||||
// version locking.
|
||||
//
|
||||
// Currently, all providers except builtin and legacy providers are eligible
|
||||
// for locking.
|
||||
func ProviderIsLockable(addr addrs.Provider) bool {
|
||||
return !(addr.IsBuiltIn() || addr.IsLegacy())
|
||||
}
|
||||
|
||||
// Sources returns the source code of the file the receiver was generated from,
|
||||
// or an empty map if the receiver wasn't generated from a file.
|
||||
//
|
||||
|
|
|
@ -237,6 +237,27 @@ func decodeProviderLockFromHCL(block *hcl.Block) (*ProviderLock, tfdiags.Diagnos
|
|||
})
|
||||
return nil, diags
|
||||
}
|
||||
if !ProviderIsLockable(addr) {
|
||||
if addr.IsBuiltIn() {
|
||||
// A specialized error for built-in providers, because we have an
|
||||
// explicit explanation for why those are not allowed.
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider source address",
|
||||
Detail: fmt.Sprintf("Cannot lock a version for built-in provider %s. Built-in providers are bundled inside Terraform itself, so you can't select a version for them independently of the Terraform release you are currently running.", addr),
|
||||
Subject: block.LabelRanges[0].Ptr(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
// Otherwise, we'll use a generic error message.
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid provider source address",
|
||||
Detail: fmt.Sprintf("Provider source address %s is a special provider that is not eligible for dependency locking.", addr),
|
||||
Subject: block.LabelRanges[0].Ptr(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
if canonAddr := addr.String(); canonAddr != rawAddr {
|
||||
// We also require the provider addresses in the lock file to be
|
||||
// written in fully-qualified canonical form, so that it's totally
|
||||
|
|
|
@ -32,3 +32,13 @@ provider "this/one/okay" {
|
|||
|
||||
provider "this/one/okay" { # ERROR: Duplicate provider lock
|
||||
}
|
||||
|
||||
# Legacy providers are not allowed, because they existed only to
|
||||
# support the Terraform 0.13 upgrade process.
|
||||
provider "registry.terraform.io/-/null" { # ERROR: Invalid provider source address
|
||||
}
|
||||
|
||||
# Built-in providers are not allowed, because they are not versioned
|
||||
# independently of the Terraform CLI release they are embedded in.
|
||||
provider "terraform.io/builtin/foo" { # ERROR: Invalid provider source address
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue