backend/remote: use `state.v2` for remote state only
The API surface area is much smaller when we use the remote backend for remote state only. So in order to try and prevent any backwards incompatibilities when TF runs inside of TFE, we’ve split up the discovery services into `state.v2` (which can be used for remote state only configurations, so when running in TFE) and `tfe.v2.1` (which can be used for all remote configurations).
This commit is contained in:
parent
e6777105b7
commit
54736b068b
|
@ -24,7 +24,7 @@ func New() backend.Backend {
|
|||
"endpoints": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "A space-separated list of the etcd endpoints<Paste>",
|
||||
Description: "A space-separated list of the etcd endpoints",
|
||||
},
|
||||
"username": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
const (
|
||||
defaultHostname = "app.terraform.io"
|
||||
defaultParallelism = 10
|
||||
stateServiceID = "state.v2"
|
||||
tfeServiceID = "tfe.v2.1"
|
||||
)
|
||||
|
||||
|
@ -211,9 +212,17 @@ func (b *Remote) Configure(obj cty.Value) tfdiags.Diagnostics {
|
|||
}
|
||||
}
|
||||
|
||||
// Determine if we are forced to use the local backend.
|
||||
b.forceLocal = os.Getenv("TF_FORCE_LOCAL_BACKEND") != ""
|
||||
|
||||
serviceID := tfeServiceID
|
||||
if b.forceLocal {
|
||||
serviceID = stateServiceID
|
||||
}
|
||||
|
||||
// Discover the service URL for this host to confirm that it provides
|
||||
// a remote backend API and to get the version constraints.
|
||||
service, constraints, err := b.discover()
|
||||
service, constraints, err := b.discover(serviceID)
|
||||
|
||||
// First check any contraints we might have received.
|
||||
if constraints != nil {
|
||||
|
@ -313,13 +322,13 @@ func (b *Remote) Configure(obj cty.Value) tfdiags.Diagnostics {
|
|||
|
||||
// Configure a local backend for when we need to run operations locally.
|
||||
b.local = backendLocal.NewWithBackend(b)
|
||||
b.forceLocal = !entitlements.Operations || os.Getenv("TF_FORCE_LOCAL_BACKEND") != ""
|
||||
b.forceLocal = b.forceLocal || !entitlements.Operations
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// discover the remote backend API service URL and version constraints.
|
||||
func (b *Remote) discover() (*url.URL, *disco.Constraints, error) {
|
||||
func (b *Remote) discover(serviceID string) (*url.URL, *disco.Constraints, error) {
|
||||
hostname, err := svchost.ForComparison(b.hostname)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -330,7 +339,7 @@ func (b *Remote) discover() (*url.URL, *disco.Constraints, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
service, err := host.ServiceURL(tfeServiceID)
|
||||
service, err := host.ServiceURL(serviceID)
|
||||
// Return the error, unless its a disco.ErrVersionNotSupported error.
|
||||
if _, ok := err.(*disco.ErrVersionNotSupported); !ok && err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -338,7 +347,7 @@ func (b *Remote) discover() (*url.URL, *disco.Constraints, error) {
|
|||
|
||||
// We purposefully ignore the error and return the previous error, as
|
||||
// checking for version constraints is considered optional.
|
||||
constraints, _ := host.VersionConstraints(tfeServiceID, "terraform")
|
||||
constraints, _ := host.VersionConstraints(serviceID, "terraform")
|
||||
|
||||
return service, constraints, err
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
tfe "github.com/hashicorp/go-tfe"
|
||||
|
@ -184,6 +185,7 @@ func testServer(t *testing.T) *httptest.Server {
|
|||
mux.HandleFunc("/well-known/terraform.json", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
io.WriteString(w, `{
|
||||
"state.v2": "/api/v2/",
|
||||
"tfe.v2.1": "/api/v2/",
|
||||
"versions.v1": "/v1/versions/"
|
||||
}`)
|
||||
|
@ -192,12 +194,12 @@ func testServer(t *testing.T) *httptest.Server {
|
|||
// Respond to service version constraints calls.
|
||||
mux.HandleFunc("/v1/versions/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
io.WriteString(w, `{
|
||||
"service": "tfe.v2.1",
|
||||
io.WriteString(w, fmt.Sprintf(`{
|
||||
"service": "%s",
|
||||
"product": "terraform",
|
||||
"minimum": "0.1.0",
|
||||
"maximum": "10.0.0"
|
||||
}`)
|
||||
}`, path.Base(r.URL.Path)))
|
||||
})
|
||||
|
||||
// Respond to the initial query to read the hashicorp org entitlements.
|
||||
|
@ -259,6 +261,7 @@ func testServer(t *testing.T) *httptest.Server {
|
|||
// localhost to a local test server.
|
||||
func testDisco(s *httptest.Server) *disco.Disco {
|
||||
services := map[string]interface{}{
|
||||
"state.v2": fmt.Sprintf("%s/api/v2/", s.URL),
|
||||
"tfe.v2.1": fmt.Sprintf("%s/api/v2/", s.URL),
|
||||
"versions.v1": fmt.Sprintf("%s/v1/versions/", s.URL),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue