Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
jbardin authored Jun 10, 2019
2 parents 3f44dd9 + 0abb0a0 commit 0c91d22
Show file tree
Hide file tree
Showing 476 changed files with 58,616 additions and 11,976 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/provider_issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Here are some of the most common:

* [AWS](https://github.com/terraform-providers/terraform-provider-aws)
* [Azure](https://github.com/terraform-providers/terraform-provider-azurerm)
* [Google](https://github.com/terraform-providers/terraform-provider-aws)
* [Google](https://github.com/terraform-providers/terraform-provider-google)
* [Oracle](https://github.com/terraform-providers/terraform-provider-oci)
* [Kubernetes](https://github.com/terraform-providers/terraform-provider-kubernetes)

Expand Down
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.12.1
1.12.4
8 changes: 8 additions & 0 deletions .tfdev
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version_info {
commit_var = "main.GitCommit"
version_var = "github.com/hashicorp/terraform/version.Version"
prerelease_var = "github.com/hashicorp/terraform/version.Prerelease"
}

version_exec = false
disable_provider_requirements = true
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
- docker
language: go
go:
- "1.12.1"
- "1.12.4"

# add TF_CONSUL_TEST=1 to run consul tests
# they were causing timouts in travis
Expand Down
1,755 changes: 63 additions & 1,692 deletions CHANGELOG.md

Large diffs are not rendered by default.

92 changes: 0 additions & 92 deletions Vagrantfile

This file was deleted.

7 changes: 4 additions & 3 deletions backend/local/backend_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,10 @@ func (b *Local) renderPlan(plan *plans.Plan, state *states.State, schemas *terra
// check if the change is due to a tainted resource
tainted := false
if !state.Empty() {
rs := state.ResourceInstance(rcs.Addr)
if rs != nil {
tainted = rs.Current.Status == states.ObjectTainted
if is := state.ResourceInstance(rcs.Addr); is != nil {
if obj := is.GetGeneration(rcs.DeposedKey.Generation()); obj != nil {
tainted = obj.Status == states.ObjectTainted
}
}
}

Expand Down
115 changes: 115 additions & 0 deletions backend/local/backend_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,121 @@ Plan: 1 to add, 0 to change, 1 to destroy.`
}
}

func TestLocal_planDeposedOnly(t *testing.T) {
b, cleanup := TestLocal(t)
defer cleanup()
p := TestLocalProvider(t, b, "test", planFixtureSchema())
testStateFile(t, b.StatePath, states.BuildState(func(ss *states.SyncState) {
ss.SetResourceInstanceDeposed(
addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_instance",
Name: "foo",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
states.DeposedKey("00000000"),
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{
"ami": "bar",
"network_interface": [{
"device_index": 0,
"description": "Main network interface"
}]
}`),
},
addrs.ProviderConfig{
Type: "test",
}.Absolute(addrs.RootModuleInstance),
)
}))
b.CLI = cli.NewMockUi()
outDir := testTempDir(t)
defer os.RemoveAll(outDir)
planPath := filepath.Join(outDir, "plan.tfplan")
op, configCleanup := testOperationPlan(t, "./test-fixtures/plan")
defer configCleanup()
op.PlanRefresh = true
op.PlanOutPath = planPath
cfg := cty.ObjectVal(map[string]cty.Value{
"path": cty.StringVal(b.StatePath),
})
cfgRaw, err := plans.NewDynamicValue(cfg, cfg.Type())
if err != nil {
t.Fatal(err)
}
op.PlanOutBackend = &plans.Backend{
// Just a placeholder so that we can generate a valid plan file.
Type: "local",
Config: cfgRaw,
}
run, err := b.Operation(context.Background(), op)
if err != nil {
t.Fatalf("bad: %s", err)
}
<-run.Done()
if run.Result != backend.OperationSuccess {
t.Fatalf("plan operation failed")
}
if !p.ReadResourceCalled {
t.Fatal("ReadResource should be called")
}
if run.PlanEmpty {
t.Fatal("plan should not be empty")
}

// The deposed object and the current object are distinct, so our
// plan includes separate actions for each of them. This strange situation
// is not common: it should arise only if Terraform fails during
// a create-before-destroy when the create hasn't completed yet but
// in a severe way that prevents the previous object from being restored
// as "current".
//
// However, that situation was more common in some earlier Terraform
// versions where deposed objects were not managed properly, so this
// can arise when upgrading from an older version with deposed objects
// already in the state.
//
// This is one of the few cases where we expose the idea of "deposed" in
// the UI, including the user-unfriendly "deposed key" (00000000 in this
// case) just so that users can correlate this with what they might
// see in `terraform show` and in the subsequent apply output, because
// it's also possible for there to be _multiple_ deposed objects, in the
// unlikely event that create_before_destroy _keeps_ crashing across
// subsequent runs.
expectedOutput := `An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# test_instance.foo will be created
+ resource "test_instance" "foo" {
+ ami = "bar"
+ network_interface {
+ description = "Main network interface"
+ device_index = 0
}
}
# test_instance.foo (deposed object 00000000) will be destroyed
- resource "test_instance" "foo" {
- ami = "bar" -> null
- network_interface {
- description = "Main network interface" -> null
- device_index = 0 -> null
}
}
Plan: 1 to add, 0 to change, 1 to destroy.`
output := b.CLI.(*cli.MockUi).OutputWriter.String()
if !strings.Contains(output, expectedOutput) {
t.Fatalf("Unexpected output:\n%s\n\nwant output containing:\n%s", output, expectedOutput)
}
}

func TestLocal_planTainted_createBeforeDestroy(t *testing.T) {
b, cleanup := TestLocal(t)
defer cleanup()
Expand Down
2 changes: 1 addition & 1 deletion backend/remote-state/gcs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (c *remoteClient) Lock(info *state.LockInfo) (string, error) {
func (c *remoteClient) Unlock(id string) error {
gen, err := strconv.ParseInt(id, 10, 64)
if err != nil {
return err
return fmt.Errorf("Lock ID should be numerical value, got '%s'", id)
}

if err := c.lockFile().If(storage.Conditions{GenerationMatch: gen}).Delete(c.storageContext); err != nil {
Expand Down
30 changes: 28 additions & 2 deletions backend/remote-state/http/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"fmt"
"net/http"
"net/url"
"time"

cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/state"
Expand Down Expand Up @@ -66,6 +68,24 @@ func New() backend.Backend {
Default: false,
Description: "Whether to skip TLS verification.",
},
"retry_max": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 2,
Description: "The number of HTTP request retries.",
},
"retry_wait_min": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 1,
Description: "The minimum time in seconds to wait between HTTP request attempts.",
},
"retry_wait_max": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 30,
Description: "The maximum time in seconds to wait between HTTP request attempts.",
},
},
}

Expand Down Expand Up @@ -131,6 +151,12 @@ func (b *Backend) configure(ctx context.Context) error {
}
}

rClient := retryablehttp.NewClient()
rClient.HTTPClient = client
rClient.RetryMax = data.Get("retry_max").(int)
rClient.RetryWaitMin = time.Duration(data.Get("retry_wait_min").(int)) * time.Second
rClient.RetryWaitMax = time.Duration(data.Get("retry_wait_max").(int)) * time.Second

b.client = &httpClient{
URL: updateURL,
UpdateMethod: updateMethod,
Expand All @@ -144,7 +170,7 @@ func (b *Backend) configure(ctx context.Context) error {
Password: data.Get("password").(string),

// accessible only for testing use
Client: client,
Client: rClient,
}
return nil
}
Expand Down
13 changes: 13 additions & 0 deletions backend/remote-state/http/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package http

import (
"testing"
"time"

"github.com/hashicorp/terraform/configs"
"github.com/zclconf/go-cty/cty"
Expand Down Expand Up @@ -51,6 +52,9 @@ func TestHTTPClientFactory(t *testing.T) {
"unlock_method": cty.StringVal("BLOOP"),
"username": cty.StringVal("user"),
"password": cty.StringVal("pass"),
"retry_max": cty.StringVal("999"),
"retry_wait_min": cty.StringVal("15"),
"retry_wait_max": cty.StringVal("150"),
}

b = backend.TestBackendConfig(t, New(), configs.SynthBody("synth", conf)).(*Backend)
Expand All @@ -74,4 +78,13 @@ func TestHTTPClientFactory(t *testing.T) {
t.Fatalf("Unexpected username \"%s\" vs \"%s\" or password \"%s\" vs \"%s\"", client.Username, conf["username"],
client.Password, conf["password"])
}
if client.Client.RetryMax != 999 {
t.Fatalf("Expected retry_max \"%d\", got \"%d\"", 999, client.Client.RetryMax)
}
if client.Client.RetryWaitMin != 15*time.Second {
t.Fatalf("Expected retry_wait_min \"%s\", got \"%s\"", 15*time.Second, client.Client.RetryWaitMin)
}
if client.Client.RetryWaitMax != 150*time.Second {
t.Fatalf("Expected retry_wait_max \"%s\", got \"%s\"", 150*time.Second, client.Client.RetryWaitMax)
}
}
5 changes: 3 additions & 2 deletions backend/remote-state/http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"net/url"

"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/terraform/state"
"github.com/hashicorp/terraform/state/remote"
)
Expand All @@ -28,7 +29,7 @@ type httpClient struct {
UnlockMethod string

// HTTP
Client *http.Client
Client *retryablehttp.Client
Username string
Password string

Expand All @@ -44,7 +45,7 @@ func (c *httpClient) httpRequest(method string, url *url.URL, data *[]byte, what
}

// Create the request
req, err := http.NewRequest(method, url.String(), reader)
req, err := retryablehttp.NewRequest(method, url.String(), reader)
if err != nil {
return nil, fmt.Errorf("Failed to make %s HTTP request: %s", what, err)
}
Expand Down
Loading

0 comments on commit 0c91d22

Please sign in to comment.