diff --git a/backend/remote/backend_apply_test.go b/backend/remote/backend_apply_test.go index 87a1cbc72304..aca57bd18fda 100644 --- a/backend/remote/backend_apply_test.go +++ b/backend/remote/backend_apply_test.go @@ -299,6 +299,41 @@ func TestRemote_applyWithTarget(t *testing.T) { } } +func TestRemote_applyWithTargetIncompatibleAPIVersion(t *testing.T) { + b, bCleanup := testBackendDefault(t) + defer bCleanup() + + op, configCleanup := testOperationPlan(t, "./testdata/plan") + defer configCleanup() + + // Set the tfe client's RemoteAPIVersion to an empty string, to mimic + // API versions prior to 2.3. + b.client.SetFakeRemoteAPIVersion("") + + addr, _ := addrs.ParseAbsResourceStr("null_resource.foo") + + op.Targets = []addrs.Targetable{addr} + op.Workspace = backend.DefaultStateName + + run, err := b.Operation(context.Background(), op) + if err != nil { + t.Fatalf("error starting operation: %v", err) + } + + <-run.Done() + if run.Result == backend.OperationSuccess { + t.Fatal("expected apply operation to fail") + } + if !run.PlanEmpty { + t.Fatalf("expected plan to be empty") + } + + errOutput := b.CLI.(*cli.MockUi).ErrorWriter.String() + if !strings.Contains(errOutput, "Resource targeting is not supported") { + t.Fatalf("expected a targeting error, got: %v", errOutput) + } +} + func TestRemote_applyWithVariables(t *testing.T) { b, bCleanup := testBackendDefault(t) defer bCleanup() diff --git a/backend/remote/backend_common.go b/backend/remote/backend_common.go index b83b9d8298f5..e8d31f7c8724 100644 --- a/backend/remote/backend_common.go +++ b/backend/remote/backend_common.go @@ -316,7 +316,7 @@ func (b *Remote) costEstimate(stopCtx, cancelCtx context.Context, op *backend.Op b.CLI.Output(b.Colorize().Color("Waiting for cost estimate to complete..." + elapsed + "\n")) } continue - case "skipped_due_to_targeting": // TEMP: not available in the go-tfe library yet; will update this to be tfe.CostEstimateSkippedDueToTargeting once that's available. + case tfe.CostEstimateSkippedDueToTargeting: b.CLI.Output("Not available for this plan, because it was created with the -target option.") b.CLI.Output("\n------------------------------------------------------------------------") return nil diff --git a/backend/remote/backend_plan_test.go b/backend/remote/backend_plan_test.go index dd247e0c6dab..52b116b825a8 100644 --- a/backend/remote/backend_plan_test.go +++ b/backend/remote/backend_plan_test.go @@ -338,6 +338,41 @@ func TestRemote_planWithTarget(t *testing.T) { } } +func TestRemote_planWithTargetIncompatibleAPIVersion(t *testing.T) { + b, bCleanup := testBackendDefault(t) + defer bCleanup() + + op, configCleanup := testOperationPlan(t, "./testdata/plan") + defer configCleanup() + + // Set the tfe client's RemoteAPIVersion to an empty string, to mimic + // API versions prior to 2.3. + b.client.SetFakeRemoteAPIVersion("") + + addr, _ := addrs.ParseAbsResourceStr("null_resource.foo") + + op.Targets = []addrs.Targetable{addr} + op.Workspace = backend.DefaultStateName + + run, err := b.Operation(context.Background(), op) + if err != nil { + t.Fatalf("error starting operation: %v", err) + } + + <-run.Done() + if run.Result == backend.OperationSuccess { + t.Fatal("expected plan operation to fail") + } + if !run.PlanEmpty { + t.Fatalf("expected plan to be empty") + } + + errOutput := b.CLI.(*cli.MockUi).ErrorWriter.String() + if !strings.Contains(errOutput, "Resource targeting is not supported") { + t.Fatalf("expected a targeting error, got: %v", errOutput) + } +} + func TestRemote_planWithVariables(t *testing.T) { b, bCleanup := testBackendDefault(t) defer bCleanup() diff --git a/go.mod b/go.mod index 3fdcf327f0c6..41bc1f5bddbc 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.5.2 github.com/hashicorp/go-rootcerts v1.0.0 github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect - github.com/hashicorp/go-tfe v0.8.0 + github.com/hashicorp/go-tfe v0.8.1 github.com/hashicorp/go-uuid v1.0.1 github.com/hashicorp/go-version v1.2.0 github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f diff --git a/go.sum b/go.sum index a555520eb669..98adccf1cf94 100644 --- a/go.sum +++ b/go.sum @@ -233,6 +233,8 @@ github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 h1:7YOlAIO2Y github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-tfe v0.8.0 h1:kz3x3tbIKRkEAzKg05P/qbFY88fkEU7TiSX3w8xUrmE= github.com/hashicorp/go-tfe v0.8.0/go.mod h1:XAV72S4O1iP8BDaqiaPLmL2B4EE6almocnOn8E8stHc= +github.com/hashicorp/go-tfe v0.8.1 h1:J6ulpLaKPHrcnwudRjxvlMYIGzqQFlnPhg3SVFh5N4E= +github.com/hashicorp/go-tfe v0.8.1/go.mod h1:XAV72S4O1iP8BDaqiaPLmL2B4EE6almocnOn8E8stHc= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= diff --git a/vendor/github.com/hashicorp/go-tfe/cost_estimate.go b/vendor/github.com/hashicorp/go-tfe/cost_estimate.go index b0ccecfb4b26..c7f33493f958 100644 --- a/vendor/github.com/hashicorp/go-tfe/cost_estimate.go +++ b/vendor/github.com/hashicorp/go-tfe/cost_estimate.go @@ -33,13 +33,14 @@ type costEstimates struct { // CostEstimateStatus represents a costEstimate state. type CostEstimateStatus string -//List all available costEstimate statuses. +// List all available costEstimate statuses. const ( - CostEstimateCanceled CostEstimateStatus = "canceled" - CostEstimateErrored CostEstimateStatus = "errored" - CostEstimateFinished CostEstimateStatus = "finished" - CostEstimatePending CostEstimateStatus = "pending" - CostEstimateQueued CostEstimateStatus = "queued" + CostEstimateCanceled CostEstimateStatus = "canceled" + CostEstimateErrored CostEstimateStatus = "errored" + CostEstimateFinished CostEstimateStatus = "finished" + CostEstimatePending CostEstimateStatus = "pending" + CostEstimateQueued CostEstimateStatus = "queued" + CostEstimateSkippedDueToTargeting CostEstimateStatus = "skipped_due_to_targeting" ) // CostEstimate represents a Terraform Enterprise costEstimate. @@ -58,11 +59,12 @@ type CostEstimate struct { // CostEstimateStatusTimestamps holds the timestamps for individual costEstimate statuses. type CostEstimateStatusTimestamps struct { - CanceledAt time.Time `json:"canceled-at"` - ErroredAt time.Time `json:"errored-at"` - FinishedAt time.Time `json:"finished-at"` - PendingAt time.Time `json:"pending-at"` - QueuedAt time.Time `json:"queued-at"` + CanceledAt time.Time `json:"canceled-at"` + ErroredAt time.Time `json:"errored-at"` + FinishedAt time.Time `json:"finished-at"` + PendingAt time.Time `json:"pending-at"` + QueuedAt time.Time `json:"queued-at"` + SkippedDueToTargetingAt time.Time `json:"skipped-due-to-targeting-at"` } // Read a costEstimate by its ID. diff --git a/vendor/github.com/hashicorp/go-tfe/tfe.go b/vendor/github.com/hashicorp/go-tfe/tfe.go index 5883d9d872d0..ca2f12d134bf 100644 --- a/vendor/github.com/hashicorp/go-tfe/tfe.go +++ b/vendor/github.com/hashicorp/go-tfe/tfe.go @@ -259,6 +259,15 @@ func (c *Client) RemoteAPIVersion() string { return c.remoteAPIVersion } +// SetFakeRemoteAPIVersion allows setting a given string as the client's remoteAPIVersion, +// overriding the value pulled from the API header during client initialization. +// +// This is intended for use in tests, when you may want to configure your TFE client to +// return something different than the actual API version in order to test error handling. +func (c *Client) SetFakeRemoteAPIVersion(fakeAPIVersion string) { + c.remoteAPIVersion = fakeAPIVersion +} + // RetryServerErrors configures the retry HTTP check to also retry // unexpected errors or requests that failed with a server error. func (c *Client) RetryServerErrors(retry bool) { diff --git a/vendor/modules.txt b/vendor/modules.txt index c092a799503f..cef6aa8b3ead 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -348,7 +348,7 @@ github.com/hashicorp/go-safetemp github.com/hashicorp/go-slug # github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 ## explicit -# github.com/hashicorp/go-tfe v0.8.0 +# github.com/hashicorp/go-tfe v0.8.1 ## explicit github.com/hashicorp/go-tfe # github.com/hashicorp/go-uuid v1.0.1