From ace192c5cd6fcff72a5a2dceccc5d31b970b7a0f Mon Sep 17 00:00:00 2001 From: Stevie Zollo Date: Thu, 4 Aug 2016 01:52:21 +0100 Subject: [PATCH 001/100] Update AMI ID on documentation --- website/source/intro/getting-started/change.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/intro/getting-started/change.html.md b/website/source/intro/getting-started/change.html.md index 0ab6d500f7d9..20fb9ce84ec8 100644 --- a/website/source/intro/getting-started/change.html.md +++ b/website/source/intro/getting-started/change.html.md @@ -33,7 +33,7 @@ resource "aws_instance" "example" { } ``` -~> **Note:** EC2 Classic users please use AMI `ami-2106ed4c` and type `t1.micro` +~> **Note:** EC2 Classic users please use AMI `ami-656be372` and type `t1.micro` We've changed the AMI from being an Ubuntu 14.04 LTS AMI to being an Ubuntu 16.04 LTS AMI. Terraform configurations are meant to be From ed68fcc752691dbdd7436a5f0f3fe28e91aa1ea4 Mon Sep 17 00:00:00 2001 From: Christopher McKenzie Date: Wed, 17 Aug 2016 10:29:25 -0700 Subject: [PATCH 002/100] Document credentials variable and env var --- website/source/docs/state/remote/gcs.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/docs/state/remote/gcs.html.md b/website/source/docs/state/remote/gcs.html.md index d5a820664cf4..0c6fc65d5244 100644 --- a/website/source/docs/state/remote/gcs.html.md +++ b/website/source/docs/state/remote/gcs.html.md @@ -53,3 +53,4 @@ The following configuration options are supported: * `bucket` - (Required) The name of the GCS bucket * `path` - (Required) The path where to place/look for state file inside the bucket + * `credentials` / `GOOGLE_CREDENTIALS` - (Required) Google Cloud Platform account credentials in json format From 4ad825fe08023ba09e381bbeb37815620e9b32f5 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Tue, 16 Aug 2016 19:40:05 -0700 Subject: [PATCH 003/100] core: name_prefix names now start with a timestamp This means that two resources created by the same rule will get names which sort in the order they are created. The rest of the ID is still random base32 characters; we no longer set the bit values that denote UUIDv4. The length of the ID returned by PrefixedUniqueId is not changed by this commit; that way we don't break any resources where the underlying resource has a name length limit. Fixes #8143. --- helper/resource/id.go | 53 +++++++++++++++++++++----------------- helper/resource/id_test.go | 28 +++++++++++++++++++- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/helper/resource/id.go b/helper/resource/id.go index ea0ae1916c53..6cc1b443d65c 100644 --- a/helper/resource/id.go +++ b/helper/resource/id.go @@ -5,6 +5,7 @@ import ( "encoding/base32" "fmt" "strings" + "time" ) const UniqueIdPrefix = `terraform-` @@ -16,31 +17,37 @@ func UniqueId() string { // Helper for a resource to generate a unique identifier w/ given prefix // -// This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters -// applied (base32, remove padding, downcase) to make visually distinguishing -// identifiers easier. +// After the prefix, the ID consists of a timestamp and 12 random base32 +// characters. The timestamp means that multiple IDs created with the same +// prefix will sort in the order of their creation. func PrefixedUniqueId(prefix string) string { - return fmt.Sprintf("%s%s", prefix, - strings.ToLower( - strings.Replace( - base32.StdEncoding.EncodeToString(uuidV4()), - "=", "", -1))) + // Be precise to the level nanoseconds, but remove the dot before the + // nanosecond. We assume that the randomCharacters call takes at least a + // nanosecond, so that multiple calls to this function from the same goroutine + // will have distinct ordered timestamps. + timestamp := strings.Replace( + time.Now().UTC().Format("20060102150405.000000000"), + ".", + "", 1) + // This uses 3 characters, so that the length of the unique ID is the same as + // it was before we added the timestamp prefix, which happened to be 23 + // characters. + return fmt.Sprintf("%s%s%s", prefix, timestamp, randomCharacters(3)) } -func uuidV4() []byte { - var uuid [16]byte - - // Set all the other bits to randomly (or pseudo-randomly) chosen - // values. - rand.Read(uuid[:]) - - // Set the two most significant bits (bits 6 and 7) of the - // clock_seq_hi_and_reserved to zero and one, respectively. - uuid[8] = (uuid[8] | 0x80) & 0x8f - - // Set the four most significant bits (bits 12 through 15) of the - // time_hi_and_version field to the 4-bit version number from Section 4.1.3. - uuid[6] = (uuid[6] | 0x40) & 0x4f +func randomCharacters(n int) string { + // Base32 has 5 bits of information per character. + b := randomBytes(n * 8 / 5) + chars := strings.ToLower( + strings.Replace( + base32.StdEncoding.EncodeToString(b), + "=", "", -1)) + // Trim extra characters. + return chars[:n] +} - return uuid[:] +func randomBytes(n int) []byte { + b := make([]byte, n) + rand.Read(b) + return b } diff --git a/helper/resource/id_test.go b/helper/resource/id_test.go index 245155b7ae2d..58082fdf9cd9 100644 --- a/helper/resource/id_test.go +++ b/helper/resource/id_test.go @@ -1,14 +1,18 @@ package resource import ( + "regexp" "strings" "testing" ) +var allDigits = regexp.MustCompile(`^\d+$`) +var allBase32 = regexp.MustCompile(`^[a-z234567]+$`) + func TestUniqueId(t *testing.T) { iterations := 10000 ids := make(map[string]struct{}) - var id string + var id, lastId string for i := 0; i < iterations; i++ { id = UniqueId() @@ -20,6 +24,28 @@ func TestUniqueId(t *testing.T) { t.Fatalf("Unique ID didn't have terraform- prefix! %s", id) } + rest := strings.TrimPrefix(id, "terraform-") + + if len(rest) != 26 { + t.Fatalf("Post-prefix part has wrong length! %s", rest) + } + + timestamp := rest[:23] + random := rest[23:] + + if !allDigits.MatchString(timestamp) { + t.Fatalf("Timestamp not all digits! %s", timestamp) + } + + if !allBase32.MatchString(random) { + t.Fatalf("Random part not all base32! %s", random) + } + + if lastId != "" && lastId >= id { + t.Fatalf("IDs not ordered! %s vs %s", lastId, id) + } + ids[id] = struct{}{} + lastId = id } } From af7085f6717c168d0b336215e46e204a6550d0df Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 17 Aug 2016 11:10:26 -0700 Subject: [PATCH 004/100] terraform: refactor var loading out to a helper Small style changes too --- terraform/context.go | 108 ++---------------------------- terraform/variables.go | 145 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 104 deletions(-) create mode 100644 terraform/variables.go diff --git a/terraform/context.go b/terraform/context.go index f60d5b5702ac..5940dd3f47da 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -3,7 +3,6 @@ package terraform import ( "fmt" "log" - "os" "sort" "strings" "sync" @@ -129,109 +128,10 @@ func NewContext(opts *ContextOpts) (*Context, error) { variables := make(map[string]interface{}) if opts.Module != nil { - for _, v := range opts.Module.Config().Variables { - if v.Default != nil { - if v.Type() == config.VariableTypeString { - // v.Default has already been parsed as HCL so there may be - // some stray ints in there - switch typedDefault := v.Default.(type) { - case string: - if typedDefault == "" { - continue - } - variables[v.Name] = typedDefault - case int, int64: - variables[v.Name] = fmt.Sprintf("%d", typedDefault) - case float32, float64: - variables[v.Name] = fmt.Sprintf("%f", typedDefault) - case bool: - variables[v.Name] = fmt.Sprintf("%t", typedDefault) - } - } else { - variables[v.Name] = v.Default - } - } - } - - for _, v := range os.Environ() { - if !strings.HasPrefix(v, VarEnvPrefix) { - continue - } - - // Strip off the prefix and get the value after the first "=" - idx := strings.Index(v, "=") - k := v[len(VarEnvPrefix):idx] - v = v[idx+1:] - - // Override the configuration-default values. Note that *not* finding the variable - // in configuration is OK, as we don't want to preclude people from having multiple - // sets of TF_VAR_whatever in their environment even if it is a little weird. - for _, schema := range opts.Module.Config().Variables { - if schema.Name == k { - varType := schema.Type() - varVal, err := parseVariableAsHCL(k, v, varType) - if err != nil { - return nil, err - } - switch varType { - case config.VariableTypeMap: - if existing, hasMap := variables[k]; !hasMap { - variables[k] = varVal - } else { - if existingMap, ok := existing.(map[string]interface{}); !ok { - panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) - } else { - switch typedV := varVal.(type) { - case []map[string]interface{}: - for newKey, newVal := range typedV[0] { - existingMap[newKey] = newVal - } - case map[string]interface{}: - for newKey, newVal := range typedV { - existingMap[newKey] = newVal - } - default: - panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) - } - } - } - default: - variables[k] = varVal - } - } - } - } - - for k, v := range opts.Variables { - for _, schema := range opts.Module.Config().Variables { - if schema.Name == k { - switch schema.Type() { - case config.VariableTypeMap: - if existing, hasMap := variables[k]; !hasMap { - variables[k] = v - } else { - if existingMap, ok := existing.(map[string]interface{}); !ok { - panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) - } else { - switch typedV := v.(type) { - case []map[string]interface{}: - for newKey, newVal := range typedV[0] { - existingMap[newKey] = newVal - } - case map[string]interface{}: - for newKey, newVal := range typedV { - existingMap[newKey] = newVal - } - default: - panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) - } - } - } - default: - variables[k] = v - } - } - } + var err error + variables, err = Variables(opts.Module, opts.Variables) + if err != nil { + return nil, err } } diff --git a/terraform/variables.go b/terraform/variables.go new file mode 100644 index 000000000000..95b607fd531e --- /dev/null +++ b/terraform/variables.go @@ -0,0 +1,145 @@ +package terraform + +import ( + "fmt" + "os" + "strings" + + "github.com/hashicorp/terraform/config" + "github.com/hashicorp/terraform/config/module" +) + +// Variables returns the fully loaded set of variables to use with +// ContextOpts and NewContext, loading any additional variables from +// the environment or any other sources. +// +// The given module tree doesn't need to be loaded. +func Variables( + m *module.Tree, + override map[string]interface{}) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + // Variables are loaded in the following sequence. Each additional step + // will override conflicting variable keys from prior steps: + // + // * Take default values from config + // * Take values from TF_VAR_x env vars + // * Take values specified in the "override" param which is usually + // from -var, -var-file, etc. + // + + // First load from the config + for _, v := range m.Config().Variables { + // If the var has no default, ignore + if v.Default == nil { + continue + } + + // If the type isn't a string, we use it as-is since it is a rich type + if v.Type() != config.VariableTypeString { + result[v.Name] = v.Default + continue + } + + // v.Default has already been parsed as HCL but it may be an int type + switch typedDefault := v.Default.(type) { + case string: + if typedDefault == "" { + continue + } + result[v.Name] = typedDefault + case int, int64: + result[v.Name] = fmt.Sprintf("%d", typedDefault) + case float32, float64: + result[v.Name] = fmt.Sprintf("%f", typedDefault) + case bool: + result[v.Name] = fmt.Sprintf("%t", typedDefault) + default: + panic(fmt.Sprintf( + "Unknown default var type: %T\n\n"+ + "THIS IS A BUG. Please report it.", + v.Default)) + } + } + + // Load from env vars + for _, v := range os.Environ() { + if !strings.HasPrefix(v, VarEnvPrefix) { + continue + } + + // Strip off the prefix and get the value after the first "=" + idx := strings.Index(v, "=") + k := v[len(VarEnvPrefix):idx] + v = v[idx+1:] + + // Override the configuration-default values. Note that *not* finding the variable + // in configuration is OK, as we don't want to preclude people from having multiple + // sets of TF_VAR_whatever in their environment even if it is a little weird. + for _, schema := range m.Config().Variables { + if schema.Name != k { + continue + } + + varType := schema.Type() + varVal, err := parseVariableAsHCL(k, v, varType) + if err != nil { + return nil, err + } + + switch varType { + case config.VariableTypeMap: + varSetMap(result, k, varVal) + default: + result[k] = varVal + } + } + } + + // Load from overrides + for k, v := range override { + for _, schema := range m.Config().Variables { + if schema.Name != k { + continue + } + + switch schema.Type() { + case config.VariableTypeMap: + varSetMap(result, k, v) + default: + result[k] = v + } + } + } + + return result, nil +} + +// varSetMap sets or merges the map in "v" with the key "k" in the +// "current" set of variables. This is just a private function to remove +// duplicate logic in Variables +func varSetMap(current map[string]interface{}, k string, v interface{}) { + existing, ok := current[k] + if !ok { + current[k] = v + return + } + + existingMap, ok := existing.(map[string]interface{}) + if !ok { + panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) + } + + switch typedV := v.(type) { + case []map[string]interface{}: + for newKey, newVal := range typedV[0] { + existingMap[newKey] = newVal + } + case map[string]interface{}: + for newKey, newVal := range typedV { + existingMap[newKey] = newVal + } + default: + panic(fmt.Sprintf("%s is not a map, this is a bug in Terraform.", k)) + } +} From cc5abd0815b0b89fab9387d4fa5c54f65eb19d7f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 17 Aug 2016 11:28:58 -0700 Subject: [PATCH 005/100] terraform: add tests for variables --- terraform/context_apply_test.go | 11 +- terraform/terraform_test.go | 5 +- terraform/test-fixtures/vars-basic/main.tf | 14 +++ terraform/variables_test.go | 114 +++++++++++++++++++++ 4 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 terraform/test-fixtures/vars-basic/main.tf create mode 100644 terraform/variables_test.go diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 6c2a493c58e1..d01174ed8023 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -3,7 +3,6 @@ package terraform import ( "bytes" "fmt" - "os" "reflect" "sort" "strings" @@ -4314,13 +4313,9 @@ func TestContext2Apply_vars(t *testing.T) { func TestContext2Apply_varsEnv(t *testing.T) { // Set the env var - old_ami := tempEnv(t, "TF_VAR_ami", "baz") - old_list := tempEnv(t, "TF_VAR_list", `["Hello", "World"]`) - old_map := tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`) - - defer os.Setenv("TF_VAR_ami", old_ami) - defer os.Setenv("TF_VAR_list", old_list) - defer os.Setenv("TF_VAR_list", old_map) + defer tempEnv(t, "TF_VAR_ami", "baz")() + defer tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)() + defer tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)() m := testModule(t, "apply-vars-env") p := testProvider("aws") diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index 469d5376db46..e6dc575e524d 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -47,11 +47,12 @@ func tempDir(t *testing.T) string { } // tempEnv lets you temporarily set an environment variable. It returns +// a function to defer to reset the old value. // the old value that should be set via a defer. -func tempEnv(t *testing.T, k string, v string) string { +func tempEnv(t *testing.T, k string, v string) func() { old := os.Getenv(k) os.Setenv(k, v) - return old + return func() { os.Setenv(k, old) } } func testConfig(t *testing.T, name string) *config.Config { diff --git a/terraform/test-fixtures/vars-basic/main.tf b/terraform/test-fixtures/vars-basic/main.tf new file mode 100644 index 000000000000..66fa77a8be40 --- /dev/null +++ b/terraform/test-fixtures/vars-basic/main.tf @@ -0,0 +1,14 @@ +variable "a" { + default = "foo" + type = "string" +} + +variable "b" { + default = [] + type = "list" +} + +variable "c" { + default = {} + type = "map" +} diff --git a/terraform/variables_test.go b/terraform/variables_test.go new file mode 100644 index 000000000000..45a59240a3f5 --- /dev/null +++ b/terraform/variables_test.go @@ -0,0 +1,114 @@ +package terraform + +import ( + "reflect" + "testing" +) + +func TestVariables(t *testing.T) { + cases := map[string]struct { + Module string + Env map[string]string + Override map[string]interface{} + Error bool + Expected map[string]interface{} + }{ + "config only": { + "vars-basic", + nil, + nil, + false, + map[string]interface{}{ + "a": "foo", + "b": []interface{}{}, + "c": map[string]interface{}{}, + }, + }, + + "env vars": { + "vars-basic", + map[string]string{ + "TF_VAR_a": "bar", + "TF_VAR_b": `["foo", "bar"]`, + "TF_VAR_c": `{"foo" = "bar"}`, + }, + nil, + false, + map[string]interface{}{ + "a": "bar", + "b": []interface{}{"foo", "bar"}, + "c": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + + "override": { + "vars-basic", + nil, + map[string]interface{}{ + "a": "bar", + "b": []interface{}{"foo", "bar"}, + "c": map[string]interface{}{ + "foo": "bar", + }, + }, + false, + map[string]interface{}{ + "a": "bar", + "b": []interface{}{"foo", "bar"}, + "c": map[string]interface{}{ + "foo": "bar", + }, + }, + }, + + "override partial map": { + "vars-basic", + map[string]string{ + "TF_VAR_c": `{"foo" = "a", "bar" = "baz"}`, + }, + map[string]interface{}{ + "c": map[string]interface{}{ + "foo": "bar", + }, + }, + false, + map[string]interface{}{ + "a": "foo", + "b": []interface{}{}, + "c": map[string]interface{}{ + "foo": "bar", + "bar": "baz", + }, + }, + }, + } + + for name, tc := range cases { + if name != "override partial map" { + continue + } + + // Wrapped in a func so we can get defers to work + func() { + // Set the env vars + for k, v := range tc.Env { + defer tempEnv(t, k, v)() + } + + m := testModule(t, tc.Module) + actual, err := Variables(m, tc.Override) + if (err != nil) != tc.Error { + t.Fatalf("%s: err: %s", err) + } + if err != nil { + return + } + + if !reflect.DeepEqual(actual, tc.Expected) { + t.Fatalf("%s: expected: %#v\n\ngot: %#v", name, tc.Expected, actual) + } + }() + } +} From 802de4ea28f6ee52a4054331c4d1e3294e4bbc46 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 17 Aug 2016 12:03:21 -0700 Subject: [PATCH 006/100] terraform: fix vet --- terraform/variables_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/variables_test.go b/terraform/variables_test.go index 45a59240a3f5..f620fc5c2c19 100644 --- a/terraform/variables_test.go +++ b/terraform/variables_test.go @@ -100,7 +100,7 @@ func TestVariables(t *testing.T) { m := testModule(t, tc.Module) actual, err := Variables(m, tc.Override) if (err != nil) != tc.Error { - t.Fatalf("%s: err: %s", err) + t.Fatalf("%s: err: %s", name, err) } if err != nil { return From 05cbb5c0ea15b420f585b319c4df03c16c5a17e7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 17 Aug 2016 18:54:18 -0500 Subject: [PATCH 007/100] terraform: add test for filtering nested modules --- terraform/state_filter_test.go | 14 ++++++ .../state-filter/nested-modules.tfstate | 47 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 terraform/test-fixtures/state-filter/nested-modules.tfstate diff --git a/terraform/state_filter_test.go b/terraform/state_filter_test.go index 5e66d9176d65..55a8baeb7dd7 100644 --- a/terraform/state_filter_test.go +++ b/terraform/state_filter_test.go @@ -92,6 +92,20 @@ func TestStateFilterFilter(t *testing.T) { "*terraform.InstanceState: module.consul.aws_instance.consul-green[0]", }, }, + + "nested modules": { + "nested-modules.tfstate", + []string{"module.outer"}, + []string{ + "*terraform.ModuleState: module.outer", + "*terraform.ModuleState: module.outer.module.child1", + "*terraform.ResourceState: module.outer.module.child1.aws_instance.foo", + "*terraform.InstanceState: module.outer.module.child1.aws_instance.foo", + "*terraform.ModuleState: module.outer.module.child2", + "*terraform.ResourceState: module.outer.module.child2.aws_instance.foo", + "*terraform.InstanceState: module.outer.module.child2.aws_instance.foo", + }, + }, } for n, tc := range cases { diff --git a/terraform/test-fixtures/state-filter/nested-modules.tfstate b/terraform/test-fixtures/state-filter/nested-modules.tfstate new file mode 100644 index 000000000000..282c390af690 --- /dev/null +++ b/terraform/test-fixtures/state-filter/nested-modules.tfstate @@ -0,0 +1,47 @@ +{ + "version": 1, + "serial": 12, + "modules": [ + { + "path": [ + "root", + "outer" + ], + "resources": {} + }, + { + "path": [ + "root", + "outer", + "child1" + ], + "resources": { + "aws_instance.foo": { + "type": "aws_instance", + "depends_on": [], + "primary": { + "id": "1", + "attributes": {} + } + } + } + }, + { + "path": [ + "root", + "outer", + "child2" + ], + "resources": { + "aws_instance.foo": { + "type": "aws_instance", + "depends_on": [], + "primary": { + "id": "1", + "attributes": {} + } + } + } + } + ] +} From 5bc8736dc898bc59d152641206d9bf93ac4f4afa Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Thu, 18 Aug 2016 16:23:01 +0100 Subject: [PATCH 008/100] Add allowed_address_pairs Original code from Rob Wilson --- .../resource_openstack_networking_port_v2.go | 70 ++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/builtin/providers/openstack/resource_openstack_networking_port_v2.go b/builtin/providers/openstack/resource_openstack_networking_port_v2.go index 39ea5aaad272..7becfa047d4e 100644 --- a/builtin/providers/openstack/resource_openstack_networking_port_v2.go +++ b/builtin/providers/openstack/resource_openstack_networking_port_v2.go @@ -96,6 +96,25 @@ func resourceNetworkingPortV2() *schema.Resource { }, }, }, + "allowed_address_pairs": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: false, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "mac_address": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + }, + }, }, } } @@ -108,15 +127,16 @@ func resourceNetworkingPortV2Create(d *schema.ResourceData, meta interface{}) er } createOpts := ports.CreateOpts{ - Name: d.Get("name").(string), - AdminStateUp: resourcePortAdminStateUpV2(d), - NetworkID: d.Get("network_id").(string), - MACAddress: d.Get("mac_address").(string), - TenantID: d.Get("tenant_id").(string), - DeviceOwner: d.Get("device_owner").(string), - SecurityGroups: resourcePortSecurityGroupsV2(d), - DeviceID: d.Get("device_id").(string), - FixedIPs: resourcePortFixedIpsV2(d), + Name: d.Get("name").(string), + AdminStateUp: resourcePortAdminStateUpV2(d), + NetworkID: d.Get("network_id").(string), + MACAddress: d.Get("mac_address").(string), + TenantID: d.Get("tenant_id").(string), + DeviceOwner: d.Get("device_owner").(string), + SecurityGroups: resourcePortSecurityGroupsV2(d), + DeviceID: d.Get("device_id").(string), + FixedIPs: resourcePortFixedIpsV2(d), + AllowedAddressPairs: resourceAllowedAddressPairsV2(d), } log.Printf("[DEBUG] Create Options: %#v", createOpts) @@ -176,6 +196,16 @@ func resourceNetworkingPortV2Read(d *schema.ResourceData, meta interface{}) erro } d.Set("fixed_ip", ips) + // Convert AllowedAddressPairs to list of map + var pairs []map[string]interface{} + for _, pairObject := range p.AllowedAddressPairs { + pair := make(map[string]interface{}) + pair["ip_address"] = pairObject.IPAddress + pair["mac_address"] = pairObject.MACAddress + pairs = append(pairs, pair) + } + d.Set("allowed_address_pairs", pairs) + return nil } @@ -212,6 +242,10 @@ func resourceNetworkingPortV2Update(d *schema.ResourceData, meta interface{}) er updateOpts.FixedIPs = resourcePortFixedIpsV2(d) } + if d.HasChange("allowed_address_pairs") { + updateOpts.AllowedAddressPairs = resourceAllowedAddressPairsV2(d) + } + log.Printf("[DEBUG] Updating Port %s with options: %+v", d.Id(), updateOpts) _, err = ports.Update(networkingClient, d.Id(), updateOpts).Extract() @@ -272,7 +306,25 @@ func resourcePortFixedIpsV2(d *schema.ResourceData) interface{} { } } return ip +} +func resourceAllowedAddressPairsV2(d *schema.ResourceData) []ports.AddressPair { + // ports.AddressPair + rawPairs := d.Get("allowed_address_pairs").([]interface{}) + + if len(rawPairs) == 0 { + return nil + } + + pairs := make([]ports.AddressPair, len(rawPairs)) + for i, raw := range rawPairs { + rawMap := raw.(map[string]interface{}) + pairs[i] = ports.AddressPair{ + IPAddress: rawMap["ip_address"].(string), + MACAddress: rawMap["mac_address"].(string), + } + } + return pairs } func resourcePortAdminStateUpV2(d *schema.ResourceData) *bool { From 59f66eca02d4669a5a1db9bd0b0fa12a64674631 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Wed, 17 Aug 2016 18:42:18 +0100 Subject: [PATCH 009/100] provider/aws: Add aws_alb_listener resource This commit adds the `aws_alb_listener` resource and associated acceptance tests and documentation. --- builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_alb_listener.go | 261 ++++++++++++ .../aws/resource_aws_alb_listener_test.go | 385 ++++++++++++++++++ .../aws/r/alb_listener.html.markdown | 68 ++++ website/source/layouts/aws.erb | 6 +- 5 files changed, 720 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/aws/resource_aws_alb_listener.go create mode 100644 builtin/providers/aws/resource_aws_alb_listener_test.go create mode 100644 website/source/docs/providers/aws/r/alb_listener.html.markdown diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 2573b8edb04a..f41f7e25b80e 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -153,6 +153,7 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ "aws_alb": resourceAwsAlb(), + "aws_alb_listener": resourceAwsAlbListener(), "aws_alb_target_group": resourceAwsAlbTargetGroup(), "aws_ami": resourceAwsAmi(), "aws_ami_copy": resourceAwsAmiCopy(), diff --git a/builtin/providers/aws/resource_aws_alb_listener.go b/builtin/providers/aws/resource_aws_alb_listener.go new file mode 100644 index 000000000000..a2bdf2413483 --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_listener.go @@ -0,0 +1,261 @@ +package aws + +import ( + "errors" + "fmt" + "log" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsAlbListener() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsAlbListenerCreate, + Read: resourceAwsAlbListenerRead, + Update: resourceAwsAlbListenerUpdate, + Delete: resourceAwsAlbListenerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + "load_balancer_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validateAwsAlbListenerPort, + }, + + "protocol": { + Type: schema.TypeString, + Optional: true, + Default: "HTTP", + StateFunc: func(v interface{}) string { + return strings.ToUpper(v.(string)) + }, + ValidateFunc: validateAwsAlbListenerProtocol, + }, + + "ssl_policy": { + Type: schema.TypeString, + Optional: true, + }, + + "certificate_arn": { + Type: schema.TypeString, + Optional: true, + }, + + "default_action": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target_group_arn": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAwsAlbListenerDefaultActionType, + }, + }, + }, + }, + }, + } +} + +func resourceAwsAlbListenerCreate(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.CreateListenerInput{ + LoadBalancerArn: aws.String(d.Get("load_balancer_arn").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + Protocol: aws.String(d.Get("protocol").(string)), + } + + if sslPolicy, ok := d.GetOk("ssl_policy"); ok { + params.SslPolicy = aws.String(sslPolicy.(string)) + } + + if certificateArn, ok := d.GetOk("certificate_arn"); ok { + params.Certificates = make([]*elbv2.Certificate, 1) + params.Certificates[0] = &elbv2.Certificate{ + CertificateArn: aws.String(certificateArn.(string)), + } + } + + if defaultActions := d.Get("default_action").([]interface{}); len(defaultActions) == 1 { + params.DefaultActions = make([]*elbv2.Action, len(defaultActions)) + + for i, defaultAction := range defaultActions { + defaultActionMap := defaultAction.(map[string]interface{}) + + params.DefaultActions[i] = &elbv2.Action{ + TargetGroupArn: aws.String(defaultActionMap["target_group_arn"].(string)), + Type: aws.String(defaultActionMap["type"].(string)), + } + } + } + + resp, err := elbconn.CreateListener(params) + if err != nil { + return errwrap.Wrapf("Error creating ALB Listener: {{err}}", err) + } + + if len(resp.Listeners) == 0 { + return errors.New("Error creating ALB Listener: no listeners returned in response") + } + + d.SetId(*resp.Listeners[0].ListenerArn) + + return resourceAwsAlbListenerRead(d, meta) +} + +func resourceAwsAlbListenerRead(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + resp, err := elbconn.DescribeListeners(&elbv2.DescribeListenersInput{ + ListenerArns: []*string{aws.String(d.Id())}, + }) + if err != nil { + if isListenerNotFound(err) { + log.Printf("[WARN] DescribeListeners - removing %s from state", d.Id()) + d.SetId("") + return nil + } + return errwrap.Wrapf("Error retrieving Listener: {{err}}", err) + } + + if len(resp.Listeners) != 1 { + return fmt.Errorf("Error retrieving Listener %q", d.Id()) + } + + listener := resp.Listeners[0] + + d.Set("arn", listener.ListenerArn) + d.Set("load_balancer_arn", listener.LoadBalancerArn) + d.Set("port", listener.Port) + d.Set("protocol", listener.Protocol) + d.Set("ssl_policy", listener.SslPolicy) + + if listener.Certificates != nil && len(listener.Certificates) == 1 { + d.Set("certificate_arn", listener.Certificates[0].CertificateArn) + } + + defaultActions := make([]map[string]interface{}, 0) + if listener.DefaultActions != nil && len(listener.DefaultActions) > 0 { + for _, defaultAction := range listener.DefaultActions { + action := map[string]interface{}{ + "target_group_arn": *defaultAction.TargetGroupArn, + "type": *defaultAction.Type, + } + defaultActions = append(defaultActions, action) + } + } + d.Set("default_action", defaultActions) + + return nil +} + +func resourceAwsAlbListenerUpdate(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.ModifyListenerInput{ + ListenerArn: aws.String(d.Id()), + Port: aws.Int64(int64(d.Get("port").(int))), + Protocol: aws.String(d.Get("protocol").(string)), + } + + if sslPolicy, ok := d.GetOk("ssl_policy"); ok { + params.SslPolicy = aws.String(sslPolicy.(string)) + } + + if certificateArn, ok := d.GetOk("certificate_arn"); ok { + params.Certificates = make([]*elbv2.Certificate, 1) + params.Certificates[0] = &elbv2.Certificate{ + CertificateArn: aws.String(certificateArn.(string)), + } + } + + if defaultActions := d.Get("default_action").([]interface{}); len(defaultActions) == 1 { + params.DefaultActions = make([]*elbv2.Action, len(defaultActions)) + + for i, defaultAction := range defaultActions { + defaultActionMap := defaultAction.(map[string]interface{}) + + params.DefaultActions[i] = &elbv2.Action{ + TargetGroupArn: aws.String(defaultActionMap["target_group_arn"].(string)), + Type: aws.String(defaultActionMap["type"].(string)), + } + } + } + + _, err := elbconn.ModifyListener(params) + if err != nil { + return errwrap.Wrapf("Error modifying ALB Listener: {{err}}", err) + } + + return resourceAwsAlbListenerRead(d, meta) +} + +func resourceAwsAlbListenerDelete(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + _, err := elbconn.DeleteListener(&elbv2.DeleteListenerInput{ + ListenerArn: aws.String(d.Id()), + }) + if err != nil { + return errwrap.Wrapf("Error deleting Listener: {{err}}", err) + } + + return nil +} + +func validateAwsAlbListenerPort(v interface{}, k string) (ws []string, errors []error) { + port := v.(int) + if port < 1 || port > 65536 { + errors = append(errors, fmt.Errorf("%q must be a valid port number (1-65536)", k)) + } + return +} + +func validateAwsAlbListenerProtocol(v interface{}, k string) (ws []string, errors []error) { + value := strings.ToLower(v.(string)) + if value == "http" || value == "https" { + return + } + + errors = append(errors, fmt.Errorf("%q must be either %q or %q", k, "HTTP", "HTTPS")) + return +} + +func validateAwsAlbListenerDefaultActionType(v interface{}, k string) (ws []string, errors []error) { + value := strings.ToLower(v.(string)) + if value != "forward" { + errors = append(errors, fmt.Errorf("%q must have the value %q", k, "forward")) + } + return +} + +func isListenerNotFound(err error) bool { + elberr, ok := err.(awserr.Error) + return ok && elberr.Code() == "ListenerNotFound" +} diff --git a/builtin/providers/aws/resource_aws_alb_listener_test.go b/builtin/providers/aws/resource_aws_alb_listener_test.go new file mode 100644 index 000000000000..6b41657dfebf --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_listener_test.go @@ -0,0 +1,385 @@ +package aws + +import ( + "errors" + "fmt" + "math/rand" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSALBListener_basic(t *testing.T) { + var conf elbv2.Listener + albName := fmt.Sprintf("testlistener-basic-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + targetGroupName := fmt.Sprintf("testtargetgroup-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb_listener.front_end", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBListenerConfig_basic(albName, targetGroupName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBListenerExists("aws_alb_listener.front_end", &conf), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "load_balancer_arn"), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "arn"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "protocol", "HTTP"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "port", "80"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "default_action.#", "1"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "default_action.0.type", "forward"), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "default_action.0.target_group_arn"), + ), + }, + }, + }) +} + +func TestAccAWSALBListener_https(t *testing.T) { + var conf elbv2.Listener + albName := fmt.Sprintf("testlistener-https-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + targetGroupName := fmt.Sprintf("testtargetgroup-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb_listener.front_end", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBListenerConfig_https(albName, targetGroupName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBListenerExists("aws_alb_listener.front_end", &conf), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "load_balancer_arn"), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "arn"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "protocol", "HTTPS"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "port", "443"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "default_action.#", "1"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "default_action.0.type", "forward"), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "default_action.0.target_group_arn"), + resource.TestCheckResourceAttrSet("aws_alb_listener.front_end", "certificate_arn"), + resource.TestCheckResourceAttr("aws_alb_listener.front_end", "ssl_policy", "ELBSecurityPolicy-2015-05"), + ), + }, + }, + }) +} + +func testAccCheckAWSALBListenerExists(n string, res *elbv2.Listener) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("No Listener ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + describe, err := conn.DescribeListeners(&elbv2.DescribeListenersInput{ + ListenerArns: []*string{aws.String(rs.Primary.ID)}, + }) + + if err != nil { + return err + } + + if len(describe.Listeners) != 1 || + *describe.Listeners[0].ListenerArn != rs.Primary.ID { + return errors.New("Listener not found") + } + + *res = *describe.Listeners[0] + return nil + } +} + +func testAccCheckAWSALBListenerDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_alb_listener" { + continue + } + + describe, err := conn.DescribeListeners(&elbv2.DescribeListenersInput{ + ListenerArns: []*string{aws.String(rs.Primary.ID)}, + }) + + if err == nil { + if len(describe.Listeners) != 0 && + *describe.Listeners[0].ListenerArn == rs.Primary.ID { + return fmt.Errorf("Listener %q still exists", rs.Primary.ID) + } + } + + // Verify the error + if isListenerNotFound(err) { + return nil + } else { + return errwrap.Wrapf("Unexpected error checking ALB Listener destroyed: {{err}}", err) + } + } + + return nil +} + +func testAccAWSALBListenerConfig_basic(albName, targetGroupName string) string { + return fmt.Sprintf(`resource "aws_alb_listener" "front_end" { + load_balancer_arn = "${aws_alb.alb_test.id}" + protocol = "HTTP" + port = "80" + + default_action { + target_group_arn = "${aws_alb_target_group.test.id}" + type = "forward" + } +} + +resource "aws_alb" "alb_test" { + name = "%s" + internal = false + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_alb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.alb_test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + TestName = "TestAccAWSALB_basic" + } +}`, albName, targetGroupName) +} + +func testAccAWSALBListenerConfig_https(albName, targetGroupName string) string { + return fmt.Sprintf(`resource "aws_alb_listener" "front_end" { + load_balancer_arn = "${aws_alb.alb_test.id}" + protocol = "HTTPS" + port = "443" + ssl_policy = "ELBSecurityPolicy-2015-05" + certificate_arn = "${aws_iam_server_certificate.test_cert.arn}" + + default_action { + target_group_arn = "${aws_alb_target_group.test.id}" + type = "forward" + } +} + +resource "aws_alb" "alb_test" { + name = "%s" + internal = false + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_alb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.alb_test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_iam_server_certificate" "test_cert" { + name = "terraform-test-cert-%d" + certificate_body = <aws_alb + > + aws_alb_listener + + > aws_alb_target_group - + > aws_ami From e38d41b7a71a031fa213719242c0941a94730c4f Mon Sep 17 00:00:00 2001 From: James Nugent Date: Thu, 18 Aug 2016 18:54:39 +0100 Subject: [PATCH 010/100] provider/aws: Add `arn` fields to ALB resources This commit adds an `arn` field to `aws_alb` and `aws_alb_target_group` resources, in order to present a more coherant user experience to people using resource variables in fields suffixed "arn". --- builtin/providers/aws/resource_aws_alb.go | 6 ++++++ builtin/providers/aws/resource_aws_alb_target_group.go | 6 ++++++ builtin/providers/aws/resource_aws_alb_target_group_test.go | 3 +++ builtin/providers/aws/resource_aws_alb_test.go | 3 +++ website/source/docs/providers/aws/r/alb.html.markdown | 3 ++- .../source/docs/providers/aws/r/alb_listener.html.markdown | 4 ++-- .../docs/providers/aws/r/alb_target_group.html.markdown | 3 ++- 7 files changed, 24 insertions(+), 4 deletions(-) diff --git a/builtin/providers/aws/resource_aws_alb.go b/builtin/providers/aws/resource_aws_alb.go index 1823ce7a3305..bf4fa7a8de64 100644 --- a/builtin/providers/aws/resource_aws_alb.go +++ b/builtin/providers/aws/resource_aws_alb.go @@ -22,6 +22,11 @@ func resourceAwsAlb() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "name": { Type: schema.TypeString, Required: true, @@ -164,6 +169,7 @@ func resourceAwsAlbRead(d *schema.ResourceData, meta interface{}) error { alb := describeResp.LoadBalancers[0] + d.Set("arn", alb.LoadBalancerArn) d.Set("name", alb.LoadBalancerName) d.Set("internal", (alb.Scheme != nil && *alb.Scheme == "internal")) d.Set("security_groups", flattenStringList(alb.SecurityGroups)) diff --git a/builtin/providers/aws/resource_aws_alb_target_group.go b/builtin/providers/aws/resource_aws_alb_target_group.go index bad712f5b2fe..ddf0597c35b9 100644 --- a/builtin/providers/aws/resource_aws_alb_target_group.go +++ b/builtin/providers/aws/resource_aws_alb_target_group.go @@ -25,6 +25,11 @@ func resourceAwsAlbTargetGroup() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "name": { Type: schema.TypeString, Required: true, @@ -206,6 +211,7 @@ func resourceAwsAlbTargetGroupRead(d *schema.ResourceData, meta interface{}) err targetGroup := resp.TargetGroups[0] + d.Set("arn", targetGroup.TargetGroupArn) d.Set("name", targetGroup.TargetGroupName) d.Set("port", targetGroup.Port) d.Set("protocol", targetGroup.Protocol) diff --git a/builtin/providers/aws/resource_aws_alb_target_group_test.go b/builtin/providers/aws/resource_aws_alb_target_group_test.go index 5ab86dd38f73..446757f62158 100644 --- a/builtin/providers/aws/resource_aws_alb_target_group_test.go +++ b/builtin/providers/aws/resource_aws_alb_target_group_test.go @@ -27,6 +27,7 @@ func TestAccAWSALBTargetGroup_basic(t *testing.T) { Config: testAccAWSALBTargetGroupConfig_basic(targetGroupName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &conf), + resource.TestCheckResourceAttrSet("aws_alb_target_group.test", "arn"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "name", targetGroupName), resource.TestCheckResourceAttr("aws_alb_target_group.test", "port", "443"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "protocol", "HTTPS"), @@ -64,6 +65,7 @@ func TestAccAWSALBTargetGroup_updateHealthCheck(t *testing.T) { Config: testAccAWSALBTargetGroupConfig_basic(targetGroupName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &conf), + resource.TestCheckResourceAttrSet("aws_alb_target_group.test", "arn"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "name", targetGroupName), resource.TestCheckResourceAttr("aws_alb_target_group.test", "port", "443"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "protocol", "HTTPS"), @@ -87,6 +89,7 @@ func TestAccAWSALBTargetGroup_updateHealthCheck(t *testing.T) { Config: testAccAWSALBTargetGroupConfig_updateHealthCheck(targetGroupName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &conf), + resource.TestCheckResourceAttrSet("aws_alb_target_group.test", "arn"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "name", targetGroupName), resource.TestCheckResourceAttr("aws_alb_target_group.test", "port", "443"), resource.TestCheckResourceAttr("aws_alb_target_group.test", "protocol", "HTTPS"), diff --git a/builtin/providers/aws/resource_aws_alb_test.go b/builtin/providers/aws/resource_aws_alb_test.go index 929da8d77cb9..3d6c265669c4 100644 --- a/builtin/providers/aws/resource_aws_alb_test.go +++ b/builtin/providers/aws/resource_aws_alb_test.go @@ -38,6 +38,7 @@ func TestAccAWSALB_basic(t *testing.T) { resource.TestCheckResourceAttrSet("aws_alb.alb_test", "vpc_id"), resource.TestCheckResourceAttrSet("aws_alb.alb_test", "zone_id"), resource.TestCheckResourceAttrSet("aws_alb.alb_test", "dns_name"), + resource.TestCheckResourceAttrSet("aws_alb.alb_test", "arn"), ), }, }, @@ -70,6 +71,7 @@ func TestAccAWSALB_accesslogs(t *testing.T) { resource.TestCheckResourceAttrSet("aws_alb.alb_test", "vpc_id"), resource.TestCheckResourceAttrSet("aws_alb.alb_test", "zone_id"), resource.TestCheckResourceAttrSet("aws_alb.alb_test", "dns_name"), + resource.TestCheckResourceAttrSet("aws_alb.alb_test", "arn"), ), }, @@ -91,6 +93,7 @@ func TestAccAWSALB_accesslogs(t *testing.T) { resource.TestCheckResourceAttr("aws_alb.alb_test", "access_logs.#", "1"), resource.TestCheckResourceAttr("aws_alb.alb_test", "access_logs.0.bucket", bucketName), resource.TestCheckResourceAttr("aws_alb.alb_test", "access_logs.0.prefix", "testAccAWSALBConfig_accessLogs"), + resource.TestCheckResourceAttrSet("aws_alb.alb_test", "arn"), ), }, }, diff --git a/website/source/docs/providers/aws/r/alb.html.markdown b/website/source/docs/providers/aws/r/alb.html.markdown index f02ae2db1786..ec677969815c 100644 --- a/website/source/docs/providers/aws/r/alb.html.markdown +++ b/website/source/docs/providers/aws/r/alb.html.markdown @@ -56,7 +56,8 @@ Access Logs (`access_logs`) support the following: The following attributes are exported in addition to the arguments listed above: -* `id` - The ARN of the load balancer +* `id` - The ARN of the load balancer (matches `arn`) +* `arn` - The ARN of the load balancer (matches `id`) * `dns_name` - The DNS name of the load balancer * `canonical_hosted_zone_id` - The canonical hosted zone ID of the load balancer. * `zone_id` - The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record) diff --git a/website/source/docs/providers/aws/r/alb_listener.html.markdown b/website/source/docs/providers/aws/r/alb_listener.html.markdown index 826c0c766110..dd3b02b98de7 100644 --- a/website/source/docs/providers/aws/r/alb_listener.html.markdown +++ b/website/source/docs/providers/aws/r/alb_listener.html.markdown @@ -23,14 +23,14 @@ resource "aws_alb_target_group" "front_end" { } resource "aws_alb_listener" "front_end" { - load_balancer_arn = "${aws_alb.front_end.id}" + load_balancer_arn = "${aws_alb.front_end.arn}" port = "443" protocol = "HTTPS" ssl_policy = "ELBSecurityPolicy-2015-05" certificate_arn = "arn:aws:iam::187416307283:server-certificate/test_cert_rab3wuqwgja25ct3n4jdj2tzu4" default_action { - target_group_arn = "${aws_alb_target_group.front_end.id}" + target_group_arn = "${aws_alb_target_group.front_end.arn}" type = "forward" } } diff --git a/website/source/docs/providers/aws/r/alb_target_group.html.markdown b/website/source/docs/providers/aws/r/alb_target_group.html.markdown index e13a033b54be..afc0be5bd5d5 100644 --- a/website/source/docs/providers/aws/r/alb_target_group.html.markdown +++ b/website/source/docs/providers/aws/r/alb_target_group.html.markdown @@ -49,7 +49,8 @@ Health Check Blocks (`health_check`) support the following: The following attributes are exported in addition to the arguments listed above: -* `id` - The ARN of the target group. +* `id` - The ARN of the Target Group (matches `arn`) +* `arn` - The ARN of the Target Group (matches `id`) ## Import From a44c8b87601908a32d6f7b967d1804a8aebd9416 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 15:05:42 -0400 Subject: [PATCH 011/100] terraform: state mv tests --- command/state_mv_test.go | 116 ++++++++++++++++++++++++++++++++++++ terraform/state.go | 6 ++ terraform/state_add.go | 44 +++++++++++++- terraform/state_add_test.go | 79 ++++++++++++++++++++++++ 4 files changed, 244 insertions(+), 1 deletion(-) diff --git a/command/state_mv_test.go b/command/state_mv_test.go index accdb2e0fdb7..4cca8fbdaac8 100644 --- a/command/state_mv_test.go +++ b/command/state_mv_test.go @@ -223,6 +223,87 @@ func TestStateMv_noState(t *testing.T) { } } +func TestStateMv_stateOutNew_nestedModule(t *testing.T) { + state := &terraform.State{ + Modules: []*terraform.ModuleState{ + &terraform.ModuleState{ + Path: []string{"root"}, + Resources: map[string]*terraform.ResourceState{}, + }, + + &terraform.ModuleState{ + Path: []string{"root", "foo"}, + Resources: map[string]*terraform.ResourceState{}, + }, + + &terraform.ModuleState{ + Path: []string{"root", "foo", "child1"}, + Resources: map[string]*terraform.ResourceState{ + "test_instance.foo": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "bar", + Attributes: map[string]string{ + "foo": "value", + "bar": "value", + }, + }, + }, + }, + }, + + &terraform.ModuleState{ + Path: []string{"root", "foo", "child2"}, + Resources: map[string]*terraform.ResourceState{ + "test_instance.foo": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "bar", + Attributes: map[string]string{ + "foo": "value", + "bar": "value", + }, + }, + }, + }, + }, + }, + } + + statePath := testStateFile(t, state) + stateOutPath := statePath + ".out" + + p := testProvider() + ui := new(cli.MockUi) + c := &StateMvCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-state-out", stateOutPath, + "module.foo", + "module.bar", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + // Test it is correct + testStateOutput(t, stateOutPath, testStateMvNestedModule_stateOut) + testStateOutput(t, statePath, testStateMvNestedModule_stateOutSrc) + + // Test we have backups + backups := testStateBackups(t, filepath.Dir(statePath)) + if len(backups) != 1 { + t.Fatalf("bad: %#v", backups) + } + testStateOutput(t, backups[0], testStateMvNestedModule_stateOutOriginal) +} + const testStateMvOutputOriginal = ` test_instance.baz: ID = foo @@ -245,6 +326,41 @@ test_instance.baz: foo = value ` +const testStateMvNestedModule_stateOut = ` +module.bar: + +module.bar.child1: + test_instance.foo: + ID = bar + bar = value + foo = value +module.bar.child2: + test_instance.foo: + ID = bar + bar = value + foo = value +` + +const testStateMvNestedModule_stateOutSrc = ` + +` + +const testStateMvNestedModule_stateOutOriginal = ` + +module.foo: + +module.foo.child1: + test_instance.foo: + ID = bar + bar = value + foo = value +module.foo.child2: + test_instance.foo: + ID = bar + bar = value + foo = value +` + const testStateMvOutput_stateOut = ` test_instance.bar: ID = bar diff --git a/terraform/state.go b/terraform/state.go index d6dc17194f15..05d124e063d0 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -808,6 +808,12 @@ func (m *ModuleState) IsRoot() bool { return reflect.DeepEqual(m.Path, rootModulePath) } +// IsDescendent returns true if other is a descendent of this module. +func (m *ModuleState) IsDescendent(other *ModuleState) bool { + i := len(m.Path) + return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path) +} + // Orphans returns a list of keys of resources that are in the State // but aren't present in the configuration itself. Hence, these keys // represent the state of resources that are orphans. diff --git a/terraform/state_add.go b/terraform/state_add.go index 83643a0426a9..34dd72e54e5b 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -11,6 +11,11 @@ import ( // module cannot be moved to a resource address, however a resource can be // moved to a module address (it retains the same name, under that resource). // +// The item can also be a []*ModuleState, which is the case for nested +// modules. In this case, Add will expect the zero-index to be the top-most +// module to add and will only nest children from there. For semantics, this +// is equivalent to module => module. +// // The full semantics of Add: // // ┌───────────────────────┬───────────────────────┬───────────────────────┐ @@ -65,7 +70,26 @@ func (s *State) Add(fromAddrRaw string, toAddrRaw string, raw interface{}) error } func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw interface{}) error { - src := raw.(*ModuleState).deepcopy() + // raw can be either *ModuleState or []*ModuleState. The former means + // we're moving just one module. The latter means we're moving a module + // and children. + root := raw + var rest []*ModuleState + if list, ok := raw.([]*ModuleState); ok { + // We need at least one item + if len(list) == 0 { + return fmt.Errorf("module move with no value to: %s", addr) + } + + // The first item is always the root + root = list[0] + if len(list) > 1 { + rest = list[1:] + } + } + + // Get the actual module state + src := root.(*ModuleState).deepcopy() // If the target module exists, it is an error path := append([]string{"root"}, addr.Path...) @@ -97,6 +121,22 @@ func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw i } } + // Add all the children if we have them + for _, item := range rest { + // If item isn't a descendent of our root, then ignore it + if !src.IsDescendent(item) { + continue + } + + // It is! Strip the leading prefix and attach that to our address + extra := item.Path[len(src.Path)+1:] + addrCopy := addr.Copy() + addrCopy.Path = append(addrCopy.Path, extra) + + // Add it + s.Add(fromAddr.String(), addrCopy.String(), item) + } + return nil } @@ -227,6 +267,8 @@ func detectValueAddLoc(raw interface{}) stateAddLoc { switch raw.(type) { case *ModuleState: return stateAddModule + case []*ModuleState: + return stateAddModule case *ResourceState: return stateAddResource case *InstanceState: diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index c69e99056fa0..0ace9bf86b11 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -194,6 +194,85 @@ func TestStateAdd(t *testing.T) { nil, }, + "ModuleState with children => Module Addr (new)": { + false, + "module.foo", + "module.bar", + + []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{}, + }, + + &ModuleState{ + Path: []string{"root", "foo", "child1"}, + Resources: map[string]*ResourceState{ + "test_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + + &ModuleState{ + Path: []string{"root", "foo", "child2"}, + Resources: map[string]*ResourceState{ + "test_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + + // Should be ignored + &ModuleState{ + Path: []string{"root", "bar", "child2"}, + Resources: map[string]*ResourceState{ + "test_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + }, + + &State{}, + &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root", "bar", "child1"}, + Resources: map[string]*ResourceState{ + "test_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + + &ModuleState{ + Path: []string{"root", "bar", "child2"}, + Resources: map[string]*ResourceState{ + "test_instance.foo": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + }, + }, + }, + "ResourceState => Resource Addr (new)": { false, "aws_instance.bar", From 787ab976919dd092fbd497a421c92369a692a677 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Thu, 18 Aug 2016 11:25:42 -0400 Subject: [PATCH 012/100] provider/google: add test case for GH-4222 Reproduces a non-empty plan that is now fixed after the bugfix for that issue landed. --- .../google/resource_sql_database_instance.go | 3 + .../resource_sql_database_instance_test.go | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/builtin/providers/google/resource_sql_database_instance.go b/builtin/providers/google/resource_sql_database_instance.go index 7ee5b5d66a13..a9a74e81cb43 100644 --- a/builtin/providers/google/resource_sql_database_instance.go +++ b/builtin/providers/google/resource_sql_database_instance.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/davecgh/go-spew/spew" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -486,6 +487,7 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) instance.MasterInstanceName = v.(string) } + log.Printf("[PAUL] INSERT: %s", spew.Sdump(project, instance)) op, err := config.clientSqlAdmin.Instances.Insert(project, instance).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 409 { @@ -994,6 +996,7 @@ func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{}) d.Partial(false) + log.Printf("[PAUL] UPDATE: %s", spew.Sdump(project, instance.Name, instance)) op, err := config.clientSqlAdmin.Instances.Update(project, instance.Name, instance).Do() if err != nil { return fmt.Errorf("Error, failed to update instance %s: %s", instance.Name, err) diff --git a/builtin/providers/google/resource_sql_database_instance_test.go b/builtin/providers/google/resource_sql_database_instance_test.go index 865dde53883c..15207a1886cc 100644 --- a/builtin/providers/google/resource_sql_database_instance_test.go +++ b/builtin/providers/google/resource_sql_database_instance_test.go @@ -152,6 +152,32 @@ func TestAccGoogleSqlDatabaseInstance_settings_downgrade(t *testing.T) { }) } +// GH-4222 +func TestAccGoogleSqlDatabaseInstance_authNets(t *testing.T) { + // var instance sqladmin.DatabaseInstance + databaseID := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleSqlDatabaseInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf( + testGoogleSqlDatabaseInstance_authNets_step1, databaseID), + }, + resource.TestStep{ + Config: fmt.Sprintf( + testGoogleSqlDatabaseInstance_authNets_step2, databaseID), + }, + resource.TestStep{ + Config: fmt.Sprintf( + testGoogleSqlDatabaseInstance_authNets_step1, databaseID), + }, + }, + }) +} + func testAccCheckGoogleSqlDatabaseInstanceEquals(n string, instance *sqladmin.DatabaseInstance) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -447,3 +473,38 @@ resource "google_sql_database_instance" "instance" { } } ` + +var testGoogleSqlDatabaseInstance_authNets_step1 = ` +resource "google_sql_database_instance" "instance" { + name = "tf-lw-%d" + region = "us-central" + settings { + tier = "D0" + crash_safe_replication = false + + ip_configuration { + ipv4_enabled = "true" + authorized_networks { + value = "108.12.12.12" + name = "misc" + expiration_time = "2017-11-15T16:19:00.094Z" + } + } + } +} +` + +var testGoogleSqlDatabaseInstance_authNets_step2 = ` +resource "google_sql_database_instance" "instance" { + name = "tf-lw-%d" + region = "us-central" + settings { + tier = "D0" + crash_safe_replication = false + + ip_configuration { + ipv4_enabled = "true" + } + } +} +` From 129edc5676bfc2b7dd9e1af17f38046439a4bee4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 15:10:16 -0400 Subject: [PATCH 013/100] update HIL dep for #7701 #5672 --- vendor/github.com/hashicorp/hil/builtins.go | 9 ++++ vendor/github.com/hashicorp/hil/eval.go | 15 +----- vendor/github.com/hashicorp/hil/eval_type.go | 14 ++++++ .../hashicorp/hil/evaltype_string.go | 2 +- vendor/github.com/hashicorp/hil/lang.y | 6 ++- vendor/github.com/hashicorp/hil/parse.go | 14 +++++- vendor/github.com/hashicorp/hil/y.go | 50 ++++++++++--------- vendor/github.com/hashicorp/hil/y.output | 40 +++++++-------- vendor/vendor.json | 6 +-- 9 files changed, 93 insertions(+), 63 deletions(-) create mode 100644 vendor/github.com/hashicorp/hil/eval_type.go diff --git a/vendor/github.com/hashicorp/hil/builtins.go b/vendor/github.com/hashicorp/hil/builtins.go index 8c8a34803c12..444bab3906f2 100644 --- a/vendor/github.com/hashicorp/hil/builtins.go +++ b/vendor/github.com/hashicorp/hil/builtins.go @@ -1,6 +1,7 @@ package hil import ( + "errors" "strconv" "github.com/hashicorp/hil/ast" @@ -77,8 +78,16 @@ func builtinIntMath() ast.Function { case ast.ArithmeticOpMul: result *= arg case ast.ArithmeticOpDiv: + if arg == 0 { + return nil, errors.New("divide by zero") + } + result /= arg case ast.ArithmeticOpMod: + if arg == 0 { + return nil, errors.New("divide by zero") + } + result = result % arg } } diff --git a/vendor/github.com/hashicorp/hil/eval.go b/vendor/github.com/hashicorp/hil/eval.go index 173c67f5ada5..9be0d59f6399 100644 --- a/vendor/github.com/hashicorp/hil/eval.go +++ b/vendor/github.com/hashicorp/hil/eval.go @@ -23,19 +23,6 @@ type EvalConfig struct { // semantic check on an AST tree. This will be called with the root node. type SemanticChecker func(ast.Node) error -// EvalType represents the type of the output returned from a HIL -// evaluation. -type EvalType uint32 - -const ( - TypeInvalid EvalType = 0 - TypeString EvalType = 1 << iota - TypeList - TypeMap -) - -//go:generate stringer -type=EvalType - // EvaluationResult is a struct returned from the hil.Eval function, // representing the result of an interpolation. Results are returned in their // "natural" Go structure rather than in terms of the HIL AST. For the types @@ -77,7 +64,7 @@ func Eval(root ast.Node, config *EvalConfig) (EvaluationResult, error) { Value: output, }) return EvaluationResult{ - Type: TypeMap, + Type: TypeMap, Value: val, }, err case ast.TypeString: diff --git a/vendor/github.com/hashicorp/hil/eval_type.go b/vendor/github.com/hashicorp/hil/eval_type.go new file mode 100644 index 000000000000..c78a25bbde9e --- /dev/null +++ b/vendor/github.com/hashicorp/hil/eval_type.go @@ -0,0 +1,14 @@ +package hil + +//go:generate stringer -type=EvalType eval_type.go + +// EvalType represents the type of the output returned from a HIL +// evaluation. +type EvalType uint32 + +const ( + TypeInvalid EvalType = 0 + TypeString EvalType = 1 << iota + TypeList + TypeMap +) diff --git a/vendor/github.com/hashicorp/hil/evaltype_string.go b/vendor/github.com/hashicorp/hil/evaltype_string.go index 911ff30e138b..f86907a4c159 100644 --- a/vendor/github.com/hashicorp/hil/evaltype_string.go +++ b/vendor/github.com/hashicorp/hil/evaltype_string.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -type=EvalType"; DO NOT EDIT +// Code generated by "stringer -type=EvalType eval_type.go"; DO NOT EDIT package hil diff --git a/vendor/github.com/hashicorp/hil/lang.y b/vendor/github.com/hashicorp/hil/lang.y index 67a7dc2aaaa8..46cca02e4d93 100644 --- a/vendor/github.com/hashicorp/hil/lang.y +++ b/vendor/github.com/hashicorp/hil/lang.y @@ -6,6 +6,8 @@ package hil import ( + "fmt" + "github.com/hashicorp/hil/ast" ) @@ -130,7 +132,9 @@ expr: // support *, /, etc., only -. We should fix this later with a pure // Go scanner/parser. if $1.Value.(ast.ArithmeticOp) != ast.ArithmeticOpSub { - panic("Unary - is only allowed") + if parserErr == nil { + parserErr = fmt.Errorf("Invalid unary operation: %v", $1.Value) + } } $$ = &ast.Arithmetic{ diff --git a/vendor/github.com/hashicorp/hil/parse.go b/vendor/github.com/hashicorp/hil/parse.go index dac21df3fb02..f498b5a811cc 100644 --- a/vendor/github.com/hashicorp/hil/parse.go +++ b/vendor/github.com/hashicorp/hil/parse.go @@ -8,6 +8,7 @@ import ( var parserLock sync.Mutex var parserResult ast.Node +var parserErr error // Parse parses the given program and returns an executable AST tree. func Parse(v string) (ast.Node, error) { @@ -18,6 +19,7 @@ func Parse(v string) (ast.Node, error) { defer parserLock.Unlock() // Reset our globals + parserErr = nil parserResult = nil // Create the lexer @@ -26,5 +28,15 @@ func Parse(v string) (ast.Node, error) { // Parse! parserParse(lex) - return parserResult, lex.Err + // If we have a lex error, return that + if lex.Err != nil { + return nil, lex.Err + } + + // If we have a parser error, return that + if parserErr != nil { + return nil, parserErr + } + + return parserResult, nil } diff --git a/vendor/github.com/hashicorp/hil/y.go b/vendor/github.com/hashicorp/hil/y.go index 30eb86aa7e4a..fdea7eb0da5c 100644 --- a/vendor/github.com/hashicorp/hil/y.go +++ b/vendor/github.com/hashicorp/hil/y.go @@ -5,10 +5,12 @@ import __yyfmt__ "fmt" //line lang.y:6 import ( + "fmt" + "github.com/hashicorp/hil/ast" ) -//line lang.y:14 +//line lang.y:16 type parserSymType struct { yys int node ast.Node @@ -57,7 +59,7 @@ const parserEofCode = 1 const parserErrCode = 2 const parserInitialStackSize = 16 -//line lang.y:196 +//line lang.y:200 //line yacctab:1 var parserExca = [...]int{ @@ -470,7 +472,7 @@ parserdefault: case 1: parserDollar = parserS[parserpt-0 : parserpt+1] - //line lang.y:36 + //line lang.y:38 { parserResult = &ast.LiteralNode{ Value: "", @@ -480,7 +482,7 @@ parserdefault: } case 2: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:44 + //line lang.y:46 { parserResult = parserDollar[1].node @@ -503,13 +505,13 @@ parserdefault: } case 3: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:67 + //line lang.y:69 { parserVAL.node = parserDollar[1].node } case 4: parserDollar = parserS[parserpt-2 : parserpt+1] - //line lang.y:71 + //line lang.y:73 { var result []ast.Node if c, ok := parserDollar[1].node.(*ast.Output); ok { @@ -525,37 +527,37 @@ parserdefault: } case 5: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:87 + //line lang.y:89 { parserVAL.node = parserDollar[1].node } case 6: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:91 + //line lang.y:93 { parserVAL.node = parserDollar[1].node } case 7: parserDollar = parserS[parserpt-3 : parserpt+1] - //line lang.y:97 + //line lang.y:99 { parserVAL.node = parserDollar[2].node } case 8: parserDollar = parserS[parserpt-3 : parserpt+1] - //line lang.y:103 + //line lang.y:105 { parserVAL.node = parserDollar[2].node } case 9: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:107 + //line lang.y:109 { parserVAL.node = parserDollar[1].node } case 10: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:111 + //line lang.y:113 { parserVAL.node = &ast.LiteralNode{ Value: parserDollar[1].token.Value.(int), @@ -565,7 +567,7 @@ parserdefault: } case 11: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:119 + //line lang.y:121 { parserVAL.node = &ast.LiteralNode{ Value: parserDollar[1].token.Value.(float64), @@ -575,14 +577,16 @@ parserdefault: } case 12: parserDollar = parserS[parserpt-2 : parserpt+1] - //line lang.y:127 + //line lang.y:129 { // This is REALLY jank. We assume that a singular ARITH_OP // means 0 ARITH_OP expr, which... is weird. We don't want to // support *, /, etc., only -. We should fix this later with a pure // Go scanner/parser. if parserDollar[1].token.Value.(ast.ArithmeticOp) != ast.ArithmeticOpSub { - panic("Unary - is only allowed") + if parserErr == nil { + parserErr = fmt.Errorf("Invalid unary operation: %v", parserDollar[1].token.Value) + } } parserVAL.node = &ast.Arithmetic{ @@ -596,7 +600,7 @@ parserdefault: } case 13: parserDollar = parserS[parserpt-3 : parserpt+1] - //line lang.y:146 + //line lang.y:150 { parserVAL.node = &ast.Arithmetic{ Op: parserDollar[2].token.Value.(ast.ArithmeticOp), @@ -606,19 +610,19 @@ parserdefault: } case 14: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:154 + //line lang.y:158 { parserVAL.node = &ast.VariableAccess{Name: parserDollar[1].token.Value.(string), Posx: parserDollar[1].token.Pos} } case 15: parserDollar = parserS[parserpt-4 : parserpt+1] - //line lang.y:158 + //line lang.y:162 { parserVAL.node = &ast.Call{Func: parserDollar[1].token.Value.(string), Args: parserDollar[3].nodeList, Posx: parserDollar[1].token.Pos} } case 16: parserDollar = parserS[parserpt-4 : parserpt+1] - //line lang.y:162 + //line lang.y:166 { parserVAL.node = &ast.Index{ Target: &ast.VariableAccess{ @@ -631,25 +635,25 @@ parserdefault: } case 17: parserDollar = parserS[parserpt-0 : parserpt+1] - //line lang.y:174 + //line lang.y:178 { parserVAL.nodeList = nil } case 18: parserDollar = parserS[parserpt-3 : parserpt+1] - //line lang.y:178 + //line lang.y:182 { parserVAL.nodeList = append(parserDollar[1].nodeList, parserDollar[3].node) } case 19: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:182 + //line lang.y:186 { parserVAL.nodeList = append(parserVAL.nodeList, parserDollar[1].node) } case 20: parserDollar = parserS[parserpt-1 : parserpt+1] - //line lang.y:188 + //line lang.y:192 { parserVAL.node = &ast.LiteralNode{ Value: parserDollar[1].token.Value.(string), diff --git a/vendor/github.com/hashicorp/hil/y.output b/vendor/github.com/hashicorp/hil/y.output index 26df788c5922..057f3d40a719 100644 --- a/vendor/github.com/hashicorp/hil/y.output +++ b/vendor/github.com/hashicorp/hil/y.output @@ -5,7 +5,7 @@ state 0 PROGRAM_BRACKET_LEFT shift 7 STRING shift 6 - . reduce 1 (src line 35) + . reduce 1 (src line 37) interpolation goto 5 literal goto 4 @@ -26,7 +26,7 @@ state 2 PROGRAM_BRACKET_LEFT shift 7 STRING shift 6 - . reduce 2 (src line 43) + . reduce 2 (src line 45) interpolation goto 5 literal goto 4 @@ -35,25 +35,25 @@ state 2 state 3 literalModeTop: literalModeValue. (3) - . reduce 3 (src line 65) + . reduce 3 (src line 67) state 4 literalModeValue: literal. (5) - . reduce 5 (src line 85) + . reduce 5 (src line 87) state 5 literalModeValue: interpolation. (6) - . reduce 6 (src line 90) + . reduce 6 (src line 92) state 6 literal: STRING. (20) - . reduce 20 (src line 186) + . reduce 20 (src line 190) state 7 @@ -77,7 +77,7 @@ state 7 state 8 literalModeTop: literalModeTop literalModeValue. (4) - . reduce 4 (src line 70) + . reduce 4 (src line 72) state 9 @@ -113,7 +113,7 @@ state 11 PROGRAM_BRACKET_LEFT shift 7 STRING shift 6 - . reduce 9 (src line 106) + . reduce 9 (src line 108) interpolation goto 5 literal goto 4 @@ -122,13 +122,13 @@ state 11 state 12 expr: INTEGER. (10) - . reduce 10 (src line 110) + . reduce 10 (src line 112) state 13 expr: FLOAT. (11) - . reduce 11 (src line 118) + . reduce 11 (src line 120) state 14 @@ -156,13 +156,13 @@ state 15 PAREN_LEFT shift 20 SQUARE_BRACKET_LEFT shift 21 - . reduce 14 (src line 153) + . reduce 14 (src line 157) state 16 interpolation: PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT. (7) - . reduce 7 (src line 95) + . reduce 7 (src line 97) state 17 @@ -196,7 +196,7 @@ state 19 expr: ARITH_OP expr. (12) expr: expr.ARITH_OP expr - . reduce 12 (src line 126) + . reduce 12 (src line 128) state 20 @@ -210,7 +210,7 @@ state 20 INTEGER shift 12 FLOAT shift 13 STRING shift 6 - . reduce 17 (src line 173) + . reduce 17 (src line 177) expr goto 25 interpolation goto 5 @@ -241,13 +241,13 @@ state 22 expr: expr.ARITH_OP expr expr: expr ARITH_OP expr. (13) - . reduce 13 (src line 145) + . reduce 13 (src line 149) state 23 expr: PAREN_LEFT expr PAREN_RIGHT. (8) - . reduce 8 (src line 101) + . reduce 8 (src line 103) state 24 @@ -264,7 +264,7 @@ state 25 args: expr. (19) ARITH_OP shift 17 - . reduce 19 (src line 181) + . reduce 19 (src line 185) state 26 @@ -279,7 +279,7 @@ state 26 state 27 expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (15) - . reduce 15 (src line 157) + . reduce 15 (src line 161) state 28 @@ -303,7 +303,7 @@ state 28 state 29 expr: IDENTIFIER SQUARE_BRACKET_LEFT expr SQUARE_BRACKET_RIGHT. (16) - . reduce 16 (src line 161) + . reduce 16 (src line 165) state 30 @@ -311,7 +311,7 @@ state 30 args: args COMMA expr. (18) ARITH_OP shift 17 - . reduce 18 (src line 177) + . reduce 18 (src line 181) 17 terminals, 8 nonterminals diff --git a/vendor/vendor.json b/vendor/vendor.json index 244b9587807e..ed1a11febd18 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1021,10 +1021,10 @@ "revisionTime": "2016-07-11T23:17:52Z" }, { - "checksumSHA1": "kqCMCHy2b+RBMKC+ER+OPqp8C3E=", + "checksumSHA1": "OrnLOmhc0FcHYs02wtbu1siIsnM=", "path": "github.com/hashicorp/hil", - "revision": "1e86c6b523c55d1fa6c6e930ce80b548664c95c2", - "revisionTime": "2016-07-11T23:18:37Z" + "revision": "227af97932d6a832b7d50a82cb1d72ddebecb9ae", + "revisionTime": "2016-08-18T19:04:49Z" }, { "checksumSHA1": "UICubs001+Q4MsUf9zl2vcMzWQQ=", From c8a9c068a25430918399b565705feadb3999419b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 15:11:16 -0400 Subject: [PATCH 014/100] update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8335efc8f118..ccd51ff48d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,8 @@ BUG FIXES: * core: CLI will only run exact match commands [GH-7983] * core: Fix panic when resources ends up null in state file [GH-8120] * core: Fix panic when validating a count with a unprefixed variable [GH-8243] + * core: Divide by zero in interpolations no longer panics [GH-7701] + * core: Fix panic on some invalid interpolation syntax [GH-5672] * provider/aws: guard against missing image_digest in `aws_ecs_task_definition` [GH-7966] * provider/aws: `aws_cloudformation_stack` now respects `timeout_in_minutes` field when waiting for CF API to finish an update operation [GH-7997] * provider/aws: Prevent errors when `aws_s3_bucket` `acceleration_status` is not available in a given region [GH-7999] From da1cf0d83620baf1ca2d07069fc32377ebd6fc0a Mon Sep 17 00:00:00 2001 From: Noah Webb Date: Fri, 5 Aug 2016 14:30:41 -0400 Subject: [PATCH 015/100] provider/google: Support Import of'google_compute_instance_group_manager' --- ...ort_compute_instance_group_manager_test.go | 65 ++++++++++++++++++ ...resource_compute_instance_group_manager.go | 67 ++++++++++++++----- ...rce_compute_instance_group_manager_test.go | 10 +-- 3 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 builtin/providers/google/import_compute_instance_group_manager_test.go diff --git a/builtin/providers/google/import_compute_instance_group_manager_test.go b/builtin/providers/google/import_compute_instance_group_manager_test.go new file mode 100644 index 000000000000..6fc3d8e8cc1c --- /dev/null +++ b/builtin/providers/google/import_compute_instance_group_manager_test.go @@ -0,0 +1,65 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccInstanceGroupManager_importBasic(t *testing.T) { + resourceName1 := "google_compute_instance_group_manager.igm-basic" + resourceName2 := "google_compute_instance_group_manager.igm-no-tp" + template := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + target := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + igm1 := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + igm2 := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceGroupManagerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccInstanceGroupManager_basic(template, target, igm1, igm2), + }, + + resource.TestStep{ + ResourceName: resourceName1, + ImportState: true, + ImportStateVerify: true, + }, + + resource.TestStep{ + ResourceName: resourceName2, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccInstanceGroupManager_importUpdate(t *testing.T) { + resourceName := "google_compute_instance_group_manager.igm-update" + template := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + target := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + igm := fmt.Sprintf("igm-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceGroupManagerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccInstanceGroupManager_update(template, target, igm), + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/google/resource_compute_instance_group_manager.go b/builtin/providers/google/resource_compute_instance_group_manager.go index b0caa0374cb6..ff39f0234359 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager.go +++ b/builtin/providers/google/resource_compute_instance_group_manager.go @@ -4,11 +4,10 @@ import ( "fmt" "log" "strings" - - "google.golang.org/api/compute/v1" - "google.golang.org/api/googleapi" + "time" "github.com/hashicorp/terraform/helper/schema" + "google.golang.org/api/compute/v1" ) func resourceComputeInstanceGroupManager() *schema.Resource { @@ -17,6 +16,9 @@ func resourceComputeInstanceGroupManager() *schema.Resource { Read: resourceComputeInstanceGroupManagerRead, Update: resourceComputeInstanceGroupManagerUpdate, Delete: resourceComputeInstanceGroupManagerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Schema: map[string]*schema.Schema{ "base_instance_name": &schema.Schema{ @@ -80,6 +82,7 @@ func resourceComputeInstanceGroupManager() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, + Computed: true, }, "self_link": &schema.Schema{ @@ -184,6 +187,18 @@ func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta inte return resourceComputeInstanceGroupManagerRead(d, meta) } +func flattenNamedPorts(namedPorts []*compute.NamedPort) []map[string]interface{} { + result := make([]map[string]interface{}, 0, len(namedPorts)) + for _, namedPort := range namedPorts { + namedPortMap := make(map[string]interface{}) + namedPortMap["name"] = namedPort.Name + namedPortMap["port"] = namedPort.Port + result = append(result, namedPortMap) + } + return result + +} + func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) @@ -192,26 +207,42 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf return err } - manager, err := config.clientCompute.InstanceGroupManagers.Get( - project, d.Get("zone").(string), d.Id()).Do() + region, err := getRegion(d, config) if err != nil { - if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { - log.Printf("[WARN] Removing Instance Group Manager %q because it's gone", d.Get("name").(string)) - // The resource doesn't exist anymore - d.SetId("") - - return nil - } + return err + } - return fmt.Errorf("Error reading instance group manager: %s", err) + getInstanceGroupManager := func(zone string) (interface{}, error) { + return config.clientCompute.InstanceGroupManagers.Get(project, zone, d.Id()).Do() } - // Set computed fields - d.Set("named_port", manager.NamedPorts) + resource, err := getZonalResourceFromRegion(getInstanceGroupManager, region, config.clientCompute, project) + if err != nil { + return err + } + if resource == nil { + log.Printf("[WARN] Removing Instance Group Manager %q because it's gone", d.Get("name").(string)) + // The resource doesn't exist anymore + d.SetId("") + return nil + } + manager := resource.(*compute.InstanceGroupManager) + + zoneUrl := strings.Split(manager.Zone, "/") + d.Set("base_instance_name", manager.BaseInstanceName) + d.Set("instance_template", manager.InstanceTemplate) + d.Set("name", manager.Name) + d.Set("zone", zoneUrl[len(zoneUrl)-1]) + d.Set("description", manager.Description) + d.Set("project", project) + d.Set("target_size", manager.TargetSize) + d.Set("target_pools", manager.TargetPools) + d.Set("named_port", flattenNamedPorts(manager.NamedPorts)) d.Set("fingerprint", manager.Fingerprint) d.Set("instance_group", manager.InstanceGroup) d.Set("target_size", manager.TargetSize) d.Set("self_link", manager.SelfLink) + d.Set("update_strategy", "RESTART") //this field doesn't match the manager api, set to default value return nil } @@ -368,6 +399,12 @@ func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta inte zone := d.Get("zone").(string) op, err := config.clientCompute.InstanceGroupManagers.Delete(project, zone, d.Id()).Do() + attempt := 0 + for err != nil && attempt < 20 { + attempt++ + time.Sleep(2000 * time.Millisecond) + op, err = config.clientCompute.InstanceGroupManagers.Delete(project, zone, d.Id()).Do() + } if err != nil { return fmt.Errorf("Error deleting instance group manager: %s", err) } diff --git a/builtin/providers/google/resource_compute_instance_group_manager_test.go b/builtin/providers/google/resource_compute_instance_group_manager_test.go index 610793bc683b..b377bddf9741 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager_test.go +++ b/builtin/providers/google/resource_compute_instance_group_manager_test.go @@ -277,7 +277,7 @@ func testAccInstanceGroupManager_basic(template, target, igm1, igm2 string) stri tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -331,7 +331,7 @@ func testAccInstanceGroupManager_update(template, target, igm string) string { tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -380,7 +380,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -411,7 +411,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -456,7 +456,7 @@ func testAccInstanceGroupManager_updateLifecycle(tag, igm string) string { tags = ["%s"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-7-wheezy-v20160301" auto_delete = true boot = true } From 09de4f82ce60d4765cc42cf7df7f1f9318dbe804 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Thu, 18 Aug 2016 20:30:12 +0100 Subject: [PATCH 016/100] provider/aws: `aws_elasticache_replication_groups` only support Redis (#8297) * provider/aws: `aws_elasticache_replication_groups` only support Redis therefore, making our users add `engine = redis` to the configuration felt wasted * Update resource_aws_elasticache_replication_group.go * Update resource_aws_elasticache_replication_group.go * Update resource_aws_elasticache_replication_group.go * Update resource_aws_elasticache_replication_group_test.go * Update resource_aws_elasticache_replication_group_test.go * Update resource_aws_elasticache_replication_group.go --- .../aws/resource_aws_elasticache_replication_group.go | 4 +++- .../aws/resource_aws_elasticache_replication_group_test.go | 5 ----- .../aws/r/elasticache_replication_group.html.markdown | 6 ++---- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/builtin/providers/aws/resource_aws_elasticache_replication_group.go b/builtin/providers/aws/resource_aws_elasticache_replication_group.go index d1514f640142..4239863df133 100644 --- a/builtin/providers/aws/resource_aws_elasticache_replication_group.go +++ b/builtin/providers/aws/resource_aws_elasticache_replication_group.go @@ -42,6 +42,9 @@ func resourceAwsElasticacheReplicationGroup() *schema.Resource { ForceNew: true, } + resourceSchema["engine"].Required = false + resourceSchema["engine"].Optional = true + resourceSchema["engine"].Default = "redis" resourceSchema["engine"].ValidateFunc = validateAwsElastiCacheReplicationGroupEngine return &schema.Resource{ @@ -396,7 +399,6 @@ func validateAwsElastiCacheReplicationGroupEngine(v interface{}, k string) (ws [ if strings.ToLower(v.(string)) != "redis" { errors = append(errors, fmt.Errorf("The only acceptable Engine type when using Replication Groups is Redis")) } - return } diff --git a/builtin/providers/aws/resource_aws_elasticache_replication_group_test.go b/builtin/providers/aws/resource_aws_elasticache_replication_group_test.go index d7ee460d68c6..3188eebc4ceb 100644 --- a/builtin/providers/aws/resource_aws_elasticache_replication_group_test.go +++ b/builtin/providers/aws/resource_aws_elasticache_replication_group_test.go @@ -284,7 +284,6 @@ resource "aws_elasticache_security_group" "bar" { resource "aws_elasticache_replication_group" "bar" { replication_group_id = "tf-%s" replication_group_description = "test description" - engine = "redis" node_type = "cache.m1.small" number_cache_clusters = 2 port = 6379 @@ -319,7 +318,6 @@ resource "aws_elasticache_security_group" "bar" { resource "aws_elasticache_replication_group" "bar" { replication_group_id = "tf-%s" replication_group_description = "updated description" - engine = "redis" node_type = "cache.m1.small" number_cache_clusters = 2 port = 6379 @@ -354,7 +352,6 @@ resource "aws_elasticache_security_group" "bar" { resource "aws_elasticache_replication_group" "bar" { replication_group_id = "tf-%s" replication_group_description = "updated description" - engine = "redis" node_type = "cache.m1.medium" number_cache_clusters = 2 port = 6379 @@ -404,7 +401,6 @@ resource "aws_elasticache_replication_group" "bar" { replication_group_description = "test description" node_type = "cache.m1.small" number_cache_clusters = 1 - engine = "redis" port = 6379 subnet_group_name = "${aws_elasticache_subnet_group.bar.name}" security_group_ids = ["${aws_security_group.bar.id}"] @@ -466,7 +462,6 @@ resource "aws_elasticache_replication_group" "bar" { replication_group_description = "test description" node_type = "cache.m1.small" number_cache_clusters = 2 - engine = "redis" port = 6379 subnet_group_name = "${aws_elasticache_subnet_group.bar.name}" security_group_ids = ["${aws_security_group.bar.id}"] diff --git a/website/source/docs/providers/aws/r/elasticache_replication_group.html.markdown b/website/source/docs/providers/aws/r/elasticache_replication_group.html.markdown index 0682e372aa91..89d1472011e2 100644 --- a/website/source/docs/providers/aws/r/elasticache_replication_group.html.markdown +++ b/website/source/docs/providers/aws/r/elasticache_replication_group.html.markdown @@ -20,7 +20,6 @@ resource "aws_elasticache_replication_group" "bar" { replication_group_description = "test description" node_type = "cache.m1.small" number_cache_clusters = 2 - engine = "redis" port = 6379 parameter_group_name = "default.redis2.8" availability_zones = ["us-west-2a", "us-west-2b"] @@ -34,17 +33,16 @@ The following arguments are supported: * `replication_group_id` – (Required) The replication group identifier. This parameter is stored as a lowercase string. * `replication_group_description` – (Required) A user-created description for the replication group. -* `number_cache_clusters` - (Required) The number of cache clusters this replication group will initially have. +* `number_cache_clusters` - (Required) The number of cache clusters this replication group will have. If Multi-AZ is enabled , the value of this parameter must be at least 2. Changing this number will force a new resource * `node_type` - (Required) The compute and memory capacity of the nodes in the node group. -* `engine` - (Required) The name of the cache engine to be used for the cache clusters in this replication group. The only valid value is Redis. * `automatic_failover_enabled` - (Optional) Specifies whether a read-only replica will be automatically promoted to read/write primary if the existing primary fails. Defaults to `false`. * `availability_zones` - (Optional) A list of EC2 availability zones in which the replication group's cache clusters will be created. The order of the availability zones in the list is not important. * `engine_version` - (Optional) The version number of the cache engine to be used for the cache clusters in this replication group. * `parameter_group_name` - (Optional) The name of the parameter group to associate with this replication group. If this argument is omitted, the default cache parameter group for the specified engine is used. * `subnet_group_name` - (Optional) The name of the cache subnet group to be used for the replication group. * `security_group_names` - (Optional) A list of cache security group names to associate with this replication group. -* `security_group_ids` - (Optional) One or more Amazon VPC security groups associated with this replication group. +* `security_group_ids` - (Optional) One or more Amazon VPC security groups associated with this replication group. Use this parameter only when you are creating a replication group in an Amazon Virtual Private Cloud * `snapshot_arns` – (Optional) A single-element string list containing an Amazon Resource Name (ARN) of a Redis RDB snapshot file stored in Amazon S3. Example: `arn:aws:s3:::my_bucket/snapshot1.rdb` From 4f8e31d8abff0df98f387e06eb5b4a8e089fc72f Mon Sep 17 00:00:00 2001 From: James Nugent Date: Thu, 18 Aug 2016 21:23:49 +0100 Subject: [PATCH 017/100] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd51ff48d60..c79dba8824b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ FEATURES: * **New Command:** `terraform state rm` [GH-8200] * **New Provider:** `archive` [GH-7322] * **New Resource:** `aws_alb` [GH-8254] + * **New Resource:** `aws_alb_listener` [GH-8269] * **New Resource:** `aws_alb_target_group` [GH-8254] * **New Resource:** `aws_vpn_gateway_attachment` [GH-7870] * **New Resource:** `aws_load_balancer_policy` [GH-7458] From 98cc77c57a5a9f0d94452d93703e90d0519030d4 Mon Sep 17 00:00:00 2001 From: Jarrod Jackson Date: Thu, 18 Aug 2016 14:38:00 -0600 Subject: [PATCH 018/100] Correct spelling of the word certificate. --- website/source/docs/providers/tls/r/locally_signed_cert.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/providers/tls/r/locally_signed_cert.html.md b/website/source/docs/providers/tls/r/locally_signed_cert.html.md index c052c5ff97d3..aa7e8e4ad317 100644 --- a/website/source/docs/providers/tls/r/locally_signed_cert.html.md +++ b/website/source/docs/providers/tls/r/locally_signed_cert.html.md @@ -8,7 +8,7 @@ description: |- # tls\_locally\_signed\_cert -Generates a TLS ceritifcate using a *Certificate Signing Request* (CSR) and +Generates a TLS certificate using a *Certificate Signing Request* (CSR) and signs it with a provided certificate authority (CA) private key. Locally-signed certificates are generally only trusted by client software when From 89193badc42aa89365209942a13fafbc7d059de2 Mon Sep 17 00:00:00 2001 From: Lars Wander Date: Thu, 18 Aug 2016 16:41:49 -0400 Subject: [PATCH 019/100] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c79dba8824b2..35f885482e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,8 +61,7 @@ IMPROVEMENTS * provider/vsphere: Standardizing datastore references to use builtin Path func [GH-8075] * provider/consul: add tls config support to consul provider [GH-7015] * remote/consul: Support setting datacenter when using consul remote state [GH-8102] - * provider/google: Support Import of `google_compute_firewall` [GH-8236] - * provider/google: Support Import of `google_compute_instance_template` [GH-8147] + * provider/google: Support import of `google_compute_instance_template` [GH-8147], `google_compute_firewall` [GH-8236], `google_compute_target_pool` [GH-8133], `google_compute_fowarding_rule` [GH-8122], `google_compute_http_health_check` [GH-8121], `google_compute_autoscaler` [GH-8115] BUG FIXES: * core: Fix issue preventing `taint` from working with resources that had no other attributes in their diff [GH-8167] From 3892cc4e910cb41d4cd9dfbb1add3e48c4c148ac Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 17:13:53 -0400 Subject: [PATCH 020/100] terraform: fix state add with multiple ModuleStates --- terraform/state_add.go | 2 +- terraform/state_add_test.go | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/terraform/state_add.go b/terraform/state_add.go index 34dd72e54e5b..54a5732a522b 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -131,7 +131,7 @@ func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw i // It is! Strip the leading prefix and attach that to our address extra := item.Path[len(src.Path)+1:] addrCopy := addr.Copy() - addrCopy.Path = append(addrCopy.Path, extra) + addrCopy.Path = append(addrCopy.Path, extra...) // Add it s.Add(fromAddr.String(), addrCopy.String(), item) diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 0ace9bf86b11..4ecf5aab00da 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -231,7 +231,7 @@ func TestStateAdd(t *testing.T) { // Should be ignored &ModuleState{ - Path: []string{"root", "bar", "child2"}, + Path: []string{"root", "baz", "child2"}, Resources: map[string]*ResourceState{ "test_instance.foo": &ResourceState{ Type: "test_instance", @@ -246,6 +246,11 @@ func TestStateAdd(t *testing.T) { &State{}, &State{ Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root", "bar"}, + Resources: map[string]*ResourceState{}, + }, + &ModuleState{ Path: []string{"root", "bar", "child1"}, Resources: map[string]*ResourceState{ @@ -499,8 +504,8 @@ func TestStateAdd(t *testing.T) { // Verify equality if !tc.One.Equal(tc.Two) { - t.Fatalf("Bad: %s\n\n%#v\n\n%#v", k, tc.One, tc.Two) - //t.Fatalf("Bad: %s\n\n%s\n\n%s", k, tc.One.String(), tc.Two.String()) + //t.Fatalf("Bad: %s\n\n%#v\n\n%#v", k, tc.One, tc.Two) + t.Fatalf("Bad: %s\n\n%s\n\n%s", k, tc.One.String(), tc.Two.String()) } } } From 3b3f92cd9b598b2f5c560b4445e0c870f844ad6b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 17:39:07 -0400 Subject: [PATCH 021/100] terraform: fix some test failures on state add with multiple modules --- command/state_mv.go | 28 +++++++++++++++++++++++++++- command/state_mv_test.go | 1 + terraform/state_add.go | 2 +- terraform/state_add_test.go | 2 +- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/command/state_mv.go b/command/state_mv.go index 7ca5fdd4badb..b16f998281b2 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -79,13 +79,16 @@ func (c *StateMvCommand) Run(args []string) int { return 1 } + // Get the item to add to the state + add := c.addableResult(results) + // Do the actual move if err := stateFromReal.Remove(args[0]); err != nil { c.Ui.Error(fmt.Sprintf(errStateMv, err)) return 1 } - if err := stateToReal.Add(args[0], args[1], results[0].Value); err != nil { + if err := stateToReal.Add(args[0], args[1], add); err != nil { c.Ui.Error(fmt.Sprintf(errStateMv, err)) return 1 } @@ -119,6 +122,29 @@ func (c *StateMvCommand) Run(args []string) int { return 0 } +// addableResult takes the result from a filter operation and returns what to +// call State.Add with. The reason we do this is beacuse in the module case +// we must add the list of all modules returned versus just the root module. +func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) interface{} { + switch v := results[0].Value.(type) { + case *terraform.ModuleState: + // If a module state then we should add the full list of modules + result := []*terraform.ModuleState{v} + if len(results) > 1 { + for _, r := range results[1:] { + if ms, ok := r.Value.(*terraform.ModuleState); ok { + result = append(result, ms) + } + } + } + + return result + default: + // By default just add the first result + return v + } +} + func (c *StateMvCommand) Help() string { helpText := ` Usage: terraform state mv [options] ADDRESS ADDRESS diff --git a/command/state_mv_test.go b/command/state_mv_test.go index 4cca8fbdaac8..bec0504aaa7b 100644 --- a/command/state_mv_test.go +++ b/command/state_mv_test.go @@ -327,6 +327,7 @@ test_instance.baz: ` const testStateMvNestedModule_stateOut = ` + module.bar: module.bar.child1: diff --git a/terraform/state_add.go b/terraform/state_add.go index 54a5732a522b..5aa795748489 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -129,7 +129,7 @@ func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw i } // It is! Strip the leading prefix and attach that to our address - extra := item.Path[len(src.Path)+1:] + extra := item.Path[len(src.Path):] addrCopy := addr.Copy() addrCopy.Path = append(addrCopy.Path, extra...) diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 4ecf5aab00da..4270ccc03211 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -201,7 +201,7 @@ func TestStateAdd(t *testing.T) { []*ModuleState{ &ModuleState{ - Path: rootModulePath, + Path: []string{"root", "foo"}, Resources: map[string]*ResourceState{}, }, From 76910c15d6528c49fcae527bc6ccd7f1235ec37e Mon Sep 17 00:00:00 2001 From: James Nugent Date: Fri, 19 Aug 2016 00:50:43 +0100 Subject: [PATCH 022/100] docs: Remove output from `terraform_remote_state` Fixes #8296. --- .../source/docs/providers/terraform/d/remote_state.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/source/docs/providers/terraform/d/remote_state.html.md b/website/source/docs/providers/terraform/d/remote_state.html.md index 5adc371705f0..68386e8b86ae 100644 --- a/website/source/docs/providers/terraform/d/remote_state.html.md +++ b/website/source/docs/providers/terraform/d/remote_state.html.md @@ -40,4 +40,6 @@ The following attributes are exported: * `backend` - See Argument Reference above. * `config` - See Argument Reference above. -* `output` - The values of the configured `outputs` for the root module referenced by the remote state. + +In addition, each output in the remote state appears as a top level attribute +on the `terraform_remote_state` resource. From 20ca61a88a14f887b2d46d244d587e901f461da4 Mon Sep 17 00:00:00 2001 From: Christoph Blecker Date: Thu, 18 Aug 2016 17:23:15 -0700 Subject: [PATCH 023/100] Update docs to use GCP Image Families --- .../docs/providers/google/r/compute_autoscaler.html.markdown | 2 +- .../providers/google/r/compute_backend_service.html.markdown | 2 +- .../docs/providers/google/r/compute_instance.html.markdown | 2 +- .../providers/google/r/compute_instance_template.html.markdown | 2 +- website/source/docs/providers/google/r/dns_record_set.markdown | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/providers/google/r/compute_autoscaler.html.markdown b/website/source/docs/providers/google/r/compute_autoscaler.html.markdown index 3d18ed651be5..d2bd362b8df0 100644 --- a/website/source/docs/providers/google/r/compute_autoscaler.html.markdown +++ b/website/source/docs/providers/google/r/compute_autoscaler.html.markdown @@ -29,7 +29,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-cloud/debian-8" } network_interface { diff --git a/website/source/docs/providers/google/r/compute_backend_service.html.markdown b/website/source/docs/providers/google/r/compute_backend_service.html.markdown index 4b578fdc7f0b..71a2acb43c8b 100644 --- a/website/source/docs/providers/google/r/compute_backend_service.html.markdown +++ b/website/source/docs/providers/google/r/compute_backend_service.html.markdown @@ -45,7 +45,7 @@ resource "google_compute_instance_template" "foobar" { } disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-cloud/debian-8" auto_delete = true boot = true } diff --git a/website/source/docs/providers/google/r/compute_instance.html.markdown b/website/source/docs/providers/google/r/compute_instance.html.markdown index a9f1024461b5..d40618a7675c 100644 --- a/website/source/docs/providers/google/r/compute_instance.html.markdown +++ b/website/source/docs/providers/google/r/compute_instance.html.markdown @@ -25,7 +25,7 @@ resource "google_compute_instance" "default" { tags = ["foo", "bar"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-cloud/debian-8" } // Local SSD disk diff --git a/website/source/docs/providers/google/r/compute_instance_template.html.markdown b/website/source/docs/providers/google/r/compute_instance_template.html.markdown index d55acf1f5bd4..b1b92669425c 100644 --- a/website/source/docs/providers/google/r/compute_instance_template.html.markdown +++ b/website/source/docs/providers/google/r/compute_instance_template.html.markdown @@ -32,7 +32,7 @@ resource "google_compute_instance_template" "foobar" { // Create a new boot disk from an image disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-cloud/debian-8" auto_delete = true boot = true } diff --git a/website/source/docs/providers/google/r/dns_record_set.markdown b/website/source/docs/providers/google/r/dns_record_set.markdown index 40bbec9c33e0..5081091322a1 100644 --- a/website/source/docs/providers/google/r/dns_record_set.markdown +++ b/website/source/docs/providers/google/r/dns_record_set.markdown @@ -21,7 +21,7 @@ resource "google_compute_instance" "frontend" { zone = "us-central1-b" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-cloud/debian-8" } network_interface { From e5ba2cb76fc538dbd33d6d38fda357366f6cd551 Mon Sep 17 00:00:00 2001 From: Christoph Blecker Date: Thu, 18 Aug 2016 19:21:48 -0700 Subject: [PATCH 024/100] Fix AccTest for Autoscaler --- builtin/providers/google/resource_compute_autoscaler_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/providers/google/resource_compute_autoscaler_test.go b/builtin/providers/google/resource_compute_autoscaler_test.go index 00a92592f1bc..40f9fcac6c12 100644 --- a/builtin/providers/google/resource_compute_autoscaler_test.go +++ b/builtin/providers/google/resource_compute_autoscaler_test.go @@ -139,7 +139,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -196,7 +196,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-cloud/debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } From a9cc6e2838b4e73cf550743d46388b885bb5f415 Mon Sep 17 00:00:00 2001 From: Christoph Blecker Date: Thu, 18 Aug 2016 19:31:45 -0700 Subject: [PATCH 025/100] Update Google TestAcc to use Debian 8 images --- .../resource_compute_backend_service_test.go | 2 +- .../google/resource_compute_disk_test.go | 2 +- ...rce_compute_instance_group_manager_test.go | 10 +++--- .../resource_compute_instance_group_test.go | 6 ++-- ...resource_compute_instance_template_test.go | 16 +++++----- .../google/resource_compute_instance_test.go | 32 +++++++++---------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/builtin/providers/google/resource_compute_backend_service_test.go b/builtin/providers/google/resource_compute_backend_service_test.go index 41be583c14f8..74187485db04 100644 --- a/builtin/providers/google/resource_compute_backend_service_test.go +++ b/builtin/providers/google/resource_compute_backend_service_test.go @@ -277,7 +277,7 @@ resource "google_compute_instance_template" "foobar" { } disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } diff --git a/builtin/providers/google/resource_compute_disk_test.go b/builtin/providers/google/resource_compute_disk_test.go index e868437d3aa9..e18cb9945f9b 100644 --- a/builtin/providers/google/resource_compute_disk_test.go +++ b/builtin/providers/google/resource_compute_disk_test.go @@ -81,7 +81,7 @@ func testAccComputeDisk_basic(diskName string) string { return fmt.Sprintf(` resource "google_compute_disk" "foobar" { name = "%s" - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" size = 50 type = "pd-ssd" zone = "us-central1-a" diff --git a/builtin/providers/google/resource_compute_instance_group_manager_test.go b/builtin/providers/google/resource_compute_instance_group_manager_test.go index b377bddf9741..87d4ea3d878a 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager_test.go +++ b/builtin/providers/google/resource_compute_instance_group_manager_test.go @@ -277,7 +277,7 @@ func testAccInstanceGroupManager_basic(template, target, igm1, igm2 string) stri tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -331,7 +331,7 @@ func testAccInstanceGroupManager_update(template, target, igm string) string { tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -380,7 +380,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -411,7 +411,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -456,7 +456,7 @@ func testAccInstanceGroupManager_updateLifecycle(tag, igm string) string { tags = ["%s"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } diff --git a/builtin/providers/google/resource_compute_instance_group_test.go b/builtin/providers/google/resource_compute_instance_group_test.go index 4578ff7d5a43..4435454c1c3a 100644 --- a/builtin/providers/google/resource_compute_instance_group_test.go +++ b/builtin/providers/google/resource_compute_instance_group_test.go @@ -190,7 +190,7 @@ func testAccComputeInstanceGroup_basic(instance string) string { zone = "us-central1-c" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -238,7 +238,7 @@ func testAccComputeInstanceGroup_update(instance string) string { count = 1 disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -273,7 +273,7 @@ func testAccComputeInstanceGroup_update2(instance string) string { count = 3 disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { diff --git a/builtin/providers/google/resource_compute_instance_template_test.go b/builtin/providers/google/resource_compute_instance_template_test.go index ec8e2b72fd4f..b1521aa3fbca 100644 --- a/builtin/providers/google/resource_compute_instance_template_test.go +++ b/builtin/providers/google/resource_compute_instance_template_test.go @@ -26,7 +26,7 @@ func TestAccComputeInstanceTemplate_basic(t *testing.T) { "google_compute_instance_template.foobar", &instanceTemplate), testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"), testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20160301", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), ), }, }, @@ -66,7 +66,7 @@ func TestAccComputeInstanceTemplate_disks(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckComputeInstanceTemplateExists( "google_compute_instance_template.foobar", &instanceTemplate), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20160301", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803", true, true), testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false), ), }, @@ -276,7 +276,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true boot = true } @@ -310,7 +310,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" } network_interface { @@ -328,7 +328,7 @@ resource "google_compute_instance_template" "foobar" { var testAccComputeInstanceTemplate_disks = fmt.Sprintf(` resource "google_compute_disk" "foobar" { name = "instancet-test-%s" - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" size = 10 type = "pd-ssd" zone = "us-central1-a" @@ -339,7 +339,7 @@ resource "google_compute_instance_template" "foobar" { machine_type = "n1-standard-1" disk { - source_image = "debian-7-wheezy-v20160301" + source_image = "debian-8-jessie-v20160803" auto_delete = true disk_size_gb = 100 boot = true @@ -372,7 +372,7 @@ func testAccComputeInstanceTemplate_subnet_auto(network string) string { machine_type = "n1-standard-1" disk { - source_image = "debian-7-wheezy-v20160211" + source_image = "debian-8-jessie-v20160803" auto_delete = true disk_size_gb = 10 boot = true @@ -407,7 +407,7 @@ resource "google_compute_instance_template" "foobar" { region = "us-central1" disk { - source_image = "debian-7-wheezy-v20160211" + source_image = "debian-8-jessie-v20160803" auto_delete = true disk_size_gb = 10 boot = true diff --git a/builtin/providers/google/resource_compute_instance_test.go b/builtin/providers/google/resource_compute_instance_test.go index bdd8c3d3eba5..1caf8f01f4ec 100644 --- a/builtin/providers/google/resource_compute_instance_test.go +++ b/builtin/providers/google/resource_compute_instance_test.go @@ -649,7 +649,7 @@ func testAccComputeInstance_basic_deprecated_network(instance string) string { tags = ["foo", "bar"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network { @@ -671,7 +671,7 @@ func testAccComputeInstance_update_deprecated_network(instance string) string { tags = ["baz"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network { @@ -694,7 +694,7 @@ func testAccComputeInstance_basic(instance string) string { tags = ["foo", "bar"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -743,7 +743,7 @@ func testAccComputeInstance_basic3(instance string) string { tags = ["foo", "bar"] disk { - image = "debian-cloud/debian-7-wheezy-v20160301" + image = "debian-cloud/debian-8-jessie-v20160803" } network_interface { @@ -791,7 +791,7 @@ func testAccComputeInstance_basic5(instance string) string { tags = ["foo", "bar"] disk { - image = "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20160301" + image = "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20160803" } network_interface { @@ -816,7 +816,7 @@ func testAccComputeInstance_forceNewAndChangeMetadata(instance string) string { tags = ["baz"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -840,7 +840,7 @@ func testAccComputeInstance_update(instance string) string { tags = ["baz"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -867,7 +867,7 @@ func testAccComputeInstance_ip(ip, instance string) string { tags = ["foo", "bar"] disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -898,7 +898,7 @@ func testAccComputeInstance_disks(disk, instance string, autodelete bool) string zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } disk { @@ -924,7 +924,7 @@ func testAccComputeInstance_local_ssd(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } disk { @@ -947,7 +947,7 @@ func testAccComputeInstance_service_account(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -972,7 +972,7 @@ func testAccComputeInstance_scheduling(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -997,7 +997,7 @@ func testAccComputeInstance_subnet_auto(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -1028,7 +1028,7 @@ func testAccComputeInstance_subnet_custom(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -1056,7 +1056,7 @@ func testAccComputeInstance_address_auto(instance string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { @@ -1084,7 +1084,7 @@ func testAccComputeInstance_address_custom(instance, address string) string { zone = "us-central1-a" disk { - image = "debian-7-wheezy-v20160301" + image = "debian-8-jessie-v20160803" } network_interface { From 13cf04b2b7ceb49d20c5e4bd2a5eb27042773f41 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Aug 2016 22:35:30 -0400 Subject: [PATCH 026/100] providers/aws: fix error on bad session --- builtin/providers/aws/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index f40d1c4024cf..72349306306c 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -188,7 +188,7 @@ func (c *Config) Client() (interface{}, error) { // Set up base session sess, err := session.NewSession(awsConfig) if err != nil { - return nil, errwrap.Wrapf("Error creating AWS session: %s", err) + return nil, errwrap.Wrapf("Error creating AWS session: {{err}}", err) } sess.Handlers.Build.PushFrontNamed(addTerraformVersionToUserAgent) From dd33357fbb010c196aa9e2a4515d80f8977b483d Mon Sep 17 00:00:00 2001 From: kyhavlov Date: Fri, 19 Aug 2016 02:40:50 -0400 Subject: [PATCH 027/100] docs: Fix example for docker_registry_image (#8308) --- .../source/docs/providers/docker/d/registry_image.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/providers/docker/d/registry_image.html.markdown b/website/source/docs/providers/docker/d/registry_image.html.markdown index 8032e8b8b239..740ac76e4a07 100644 --- a/website/source/docs/providers/docker/d/registry_image.html.markdown +++ b/website/source/docs/providers/docker/d/registry_image.html.markdown @@ -22,7 +22,7 @@ data "docker_registry_image" "ubuntu" { } resource "docker_image" "ubuntu" { - name = "${data.docker_image.ubuntu.name}" + name = "${data.docker_registry_image.ubuntu.name}" pull_trigger = "${data.docker_registry_image.ubuntu.sha256_digest}" } ``` From 4c47e0dc37288fb69ba2e41d5f0efa78404640b6 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Fri, 19 Aug 2016 09:09:48 +0100 Subject: [PATCH 028/100] docs/aws: Fix example of aws_redshift_service_account (#8313) --- .../providers/aws/d/redshift_service_account.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/providers/aws/d/redshift_service_account.html.markdown b/website/source/docs/providers/aws/d/redshift_service_account.html.markdown index 7b203a558654..0475c29e130a 100644 --- a/website/source/docs/providers/aws/d/redshift_service_account.html.markdown +++ b/website/source/docs/providers/aws/d/redshift_service_account.html.markdown @@ -27,7 +27,7 @@ resource "aws_s3_bucket" "bucket" { "Sid": "Put bucket policy needed for audit logging", "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam:${data.aws_redshift_account_id.main.id}:user/logs" + "AWS": "arn:aws:iam:${data.aws_redshift_service_account.main.id}:user/logs" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::tf-redshift-logging-test-bucket/*" @@ -36,7 +36,7 @@ resource "aws_s3_bucket" "bucket" { "Sid": "Get bucket policy needed for audit logging ", "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam:${data.aws_redshift_account_id.main.id}:user/logs" + "AWS": "arn:aws:iam:${data.aws_redshift_service_account.main.id}:user/logs" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::tf-redshift-logging-test-bucket" From 73f0c4791588b465b680e6a20da383277657fe11 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Fri, 19 Aug 2016 09:13:39 +0100 Subject: [PATCH 029/100] aws/docs: Add example of aws_alb_target_group (#8311) --- .../providers/aws/r/alb_target_group.html.markdown | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/website/source/docs/providers/aws/r/alb_target_group.html.markdown b/website/source/docs/providers/aws/r/alb_target_group.html.markdown index afc0be5bd5d5..9ab94e4419e4 100644 --- a/website/source/docs/providers/aws/r/alb_target_group.html.markdown +++ b/website/source/docs/providers/aws/r/alb_target_group.html.markdown @@ -15,6 +15,16 @@ resources. ## Example Usage ``` +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.main.id}" +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} ``` ## Argument Reference From 5df0b08e86e80fb068269a401565d29fc1babaa0 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski Date: Fri, 19 Aug 2016 19:19:49 +0900 Subject: [PATCH 030/100] Add ability to set peering options in aws_vpc_peering_connection. (#8310) This commit adds two optional blocks called "accepter" and "requester" to the resource allowing for setting desired VPC Peering Connection options for VPCs that participate in the VPC peering. Signed-off-by: Krzysztof Wilczynski --- .../resource_aws_vpc_peering_connection.go | 142 +++++++++-- ...esource_aws_vpc_peering_connection_test.go | 229 +++++++++++++++--- .../providers/aws/r/vpc_peering.html.markdown | 62 ++++- 3 files changed, 375 insertions(+), 58 deletions(-) diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection.go b/builtin/providers/aws/resource_aws_vpc_peering_connection.go index c712e45740cb..94d3c7f6c72d 100644 --- a/builtin/providers/aws/resource_aws_vpc_peering_connection.go +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection.go @@ -47,7 +47,9 @@ func resourceAwsVpcPeeringConnection() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "accepter": vpcPeeringConnectionOptionsSchema(), + "requester": vpcPeeringConnectionOptionsSchema(), + "tags": tagsSchema(), }, } } @@ -61,7 +63,8 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error PeerVpcId: aws.String(d.Get("peer_vpc_id").(string)), VpcId: aws.String(d.Get("vpc_id").(string)), } - log.Printf("[DEBUG] VPCPeeringCreate create config: %#v", createOpts) + log.Printf("[DEBUG] VPC Peering Create options: %#v", createOpts) + resp, err := conn.CreateVpcPeeringConnection(createOpts) if err != nil { return fmt.Errorf("Error creating vpc peering connection: %s", err) @@ -73,9 +76,7 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] VPC Peering Connection ID: %s", d.Id()) // Wait for the vpc peering connection to become available - log.Printf( - "[DEBUG] Waiting for vpc peering connection (%s) to become available", - d.Id()) + log.Printf("[DEBUG] Waiting for VPC Peering Connection (%s) to become available.", d.Id()) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: []string{"pending-acceptance"}, @@ -84,7 +85,7 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error } if _, err := stateConf.WaitForState(); err != nil { return fmt.Errorf( - "Error waiting for vpc peering (%s) to become available: %s", + "Error waiting for VPC Peering Connection (%s) to become available: %s", d.Id(), err) } @@ -97,6 +98,7 @@ func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } + if pcRaw == nil { d.SetId("") return nil @@ -108,25 +110,46 @@ func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error { // connection is gone. Destruction isn't allowed, and it eventually // just "falls off" the console. See GH-2322 if pc.Status != nil { - if *pc.Status.Code == "failed" || *pc.Status.Code == "deleted" || *pc.Status.Code == "rejected" || *pc.Status.Code == "deleting" || *pc.Status.Code == "expired" { - log.Printf("[DEBUG] VPC Peering Connect (%s) in state (%s), removing", d.Id(), *pc.Status.Code) + status := map[string]bool{ + "deleted": true, + "deleting": true, + "expired": true, + "failed": true, + "rejected": true, + } + if _, ok := status[*pc.Status.Code]; ok { + log.Printf("[DEBUG] VPC Peering Connection (%s) in state (%s), removing.", + d.Id(), *pc.Status.Code) d.SetId("") return nil } } d.Set("accept_status", *pc.Status.Code) - d.Set("peer_owner_id", pc.AccepterVpcInfo.OwnerId) - d.Set("peer_vpc_id", pc.AccepterVpcInfo.VpcId) - d.Set("vpc_id", pc.RequesterVpcInfo.VpcId) - d.Set("tags", tagsToMap(pc.Tags)) + d.Set("peer_owner_id", *pc.AccepterVpcInfo.OwnerId) + d.Set("peer_vpc_id", *pc.AccepterVpcInfo.VpcId) + d.Set("vpc_id", *pc.RequesterVpcInfo.VpcId) + + err = d.Set("accepter", flattenPeeringOptions(pc.AccepterVpcInfo.PeeringOptions)) + if err != nil { + return err + } + + err = d.Set("requester", flattenPeeringOptions(pc.RequesterVpcInfo.PeeringOptions)) + if err != nil { + return err + } + + err = d.Set("tags", tagsToMap(pc.Tags)) + if err != nil { + return err + } return nil } func resourceVPCPeeringConnectionAccept(conn *ec2.EC2, id string) (string, error) { - - log.Printf("[INFO] Accept VPC Peering Connection with id: %s", id) + log.Printf("[INFO] Accept VPC Peering Connection with ID: %s", id) req := &ec2.AcceptVpcPeeringConnectionInput{ VpcPeeringConnectionId: aws.String(id), @@ -137,7 +160,37 @@ func resourceVPCPeeringConnectionAccept(conn *ec2.EC2, id string) (string, error return "", err } pc := resp.VpcPeeringConnection - return *pc.Status.Code, err + + return *pc.Status.Code, nil +} + +func resourceVPCPeeringConnectionOptionsModify(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + modifyOpts := &ec2.ModifyVpcPeeringConnectionOptionsInput{ + VpcPeeringConnectionId: aws.String(d.Id()), + } + + if v, ok := d.GetOk("accepter"); ok { + if s := v.([]interface{}); len(s) > 0 { + modifyOpts.AccepterPeeringConnectionOptions = expandPeeringOptions( + s[0].(map[string]interface{})) + } + } + + if v, ok := d.GetOk("requester"); ok { + if s := v.([]interface{}); len(s) > 0 { + modifyOpts.RequesterPeeringConnectionOptions = expandPeeringOptions( + s[0].(map[string]interface{})) + } + } + + log.Printf("[DEBUG] VPC Peering Connection modify options: %#v", modifyOpts) + if _, err := conn.ModifyVpcPeeringConnectionOptions(modifyOpts); err != nil { + return err + } + + return nil } func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error { @@ -151,10 +204,10 @@ func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error if _, ok := d.GetOk("auto_accept"); ok { pcRaw, _, err := resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id())() - if err != nil { return err } + if pcRaw == nil { d.SetId("") return nil @@ -166,9 +219,13 @@ func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error if err != nil { return err } - log.Printf( - "[DEBUG] VPC Peering connection accept status: %s", - status) + log.Printf("[DEBUG] VPC Peering Connection accept status: %s", status) + } + } + + if d.HasChange("accepter") || d.HasChange("requester") { + if err := resourceVPCPeeringConnectionOptionsModify(d, meta); err != nil { + return err } } @@ -182,6 +239,7 @@ func resourceAwsVPCPeeringDelete(d *schema.ResourceData, meta interface{}) error &ec2.DeleteVpcPeeringConnectionInput{ VpcPeeringConnectionId: aws.String(d.Id()), }) + return err } @@ -213,3 +271,49 @@ func resourceAwsVPCPeeringConnectionStateRefreshFunc(conn *ec2.EC2, id string) r return pc, *pc.Status.Code, nil } } + +func vpcPeeringConnectionOptionsSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allow_remote_vpc_dns_resolution": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "allow_classic_link_to_remote_vpc": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "allow_vpc_to_remote_classic_link": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + }, + } +} + +func flattenPeeringOptions(options *ec2.VpcPeeringConnectionOptionsDescription) (results []map[string]interface{}) { + m := map[string]interface{}{ + "allow_remote_vpc_dns_resolution": *options.AllowDnsResolutionFromRemoteVpc, + "allow_classic_link_to_remote_vpc": *options.AllowEgressFromLocalClassicLinkToRemoteVpc, + "allow_vpc_to_remote_classic_link": *options.AllowEgressFromLocalVpcToRemoteClassicLink, + } + results = append(results, m) + return +} + +func expandPeeringOptions(m map[string]interface{}) *ec2.PeeringConnectionOptionsRequest { + return &ec2.PeeringConnectionOptionsRequest{ + AllowDnsResolutionFromRemoteVpc: aws.Bool(m["allow_remote_vpc_dns_resolution"].(bool)), + AllowEgressFromLocalClassicLinkToRemoteVpc: aws.Bool(m["allow_classic_link_to_remote_vpc"].(bool)), + AllowEgressFromLocalVpcToRemoteClassicLink: aws.Bool(m["allow_vpc_to_remote_classic_link"].(bool)), + } +} diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go b/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go index 5aefdd6a9c03..67d6a60ad7f2 100644 --- a/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "os" + "reflect" "testing" "github.com/aws/aws-sdk-go/aws" @@ -19,7 +20,7 @@ func TestAccAWSVPCPeeringConnection_basic(t *testing.T) { PreCheck: func() { testAccPreCheck(t) if os.Getenv("AWS_ACCOUNT_ID") == "" { - t.Fatal("AWS_ACCOUNT_ID must be set") + t.Fatal("AWS_ACCOUNT_ID must be set.") } }, @@ -32,7 +33,9 @@ func TestAccAWSVPCPeeringConnection_basic(t *testing.T) { resource.TestStep{ Config: testAccVpcPeeringConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckAWSVpcPeeringConnectionExists("aws_vpc_peering_connection.foo", &connection), + testAccCheckAWSVpcPeeringConnectionExists( + "aws_vpc_peering_connection.foo", + &connection), ), }, }, @@ -45,7 +48,7 @@ func TestAccAWSVPCPeeringConnection_plan(t *testing.T) { // reach out and DELETE the VPC Peering connection outside of Terraform testDestroy := func(*terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn - log.Printf("[DEBUG] Test deleting VPC Peering connection") + log.Printf("[DEBUG] Test deleting the VPC Peering Connection.") _, err := conn.DeleteVpcPeeringConnection( &ec2.DeleteVpcPeeringConnectionInput{ VpcPeeringConnectionId: connection.VpcPeeringConnectionId, @@ -60,7 +63,7 @@ func TestAccAWSVPCPeeringConnection_plan(t *testing.T) { PreCheck: func() { testAccPreCheck(t) if os.Getenv("AWS_ACCOUNT_ID") == "" { - t.Fatal("AWS_ACCOUNT_ID must be set") + t.Fatal("AWS_ACCOUNT_ID must be set.") } }, Providers: testAccProviders, @@ -69,7 +72,9 @@ func TestAccAWSVPCPeeringConnection_plan(t *testing.T) { resource.TestStep{ Config: testAccVpcPeeringConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckAWSVpcPeeringConnectionExists("aws_vpc_peering_connection.foo", &connection), + testAccCheckAWSVpcPeeringConnectionExists( + "aws_vpc_peering_connection.foo", + &connection), testDestroy, ), ExpectNonEmptyPlan: true, @@ -82,7 +87,7 @@ func TestAccAWSVPCPeeringConnection_tags(t *testing.T) { var connection ec2.VpcPeeringConnection peerId := os.Getenv("TF_PEER_ID") if peerId == "" { - t.Skip("Error: TestAccAWSVPCPeeringConnection_tags requires a peer id to be set") + t.Skip("Error: TestAccAWSVPCPeeringConnection_tags requires a peer ID to be set.") } resource.Test(t, resource.TestCase{ @@ -97,7 +102,9 @@ func TestAccAWSVPCPeeringConnection_tags(t *testing.T) { resource.TestStep{ Config: fmt.Sprintf(testAccVpcPeeringConfigTags, peerId), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSVpcPeeringConnectionExists("aws_vpc_peering_connection.foo", &connection), + testAccCheckAWSVpcPeeringConnectionExists( + "aws_vpc_peering_connection.foo", + &connection), testAccCheckTags(&connection.Tags, "foo", "bar"), ), }, @@ -105,6 +112,106 @@ func TestAccAWSVPCPeeringConnection_tags(t *testing.T) { }) } +func TestAccAWSVPCPeeringConnection_options(t *testing.T) { + var connection ec2.VpcPeeringConnection + + testAccepterChange := func(*terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + log.Printf("[DEBUG] Test change to the VPC Peering Connection Options.") + + _, err := conn.ModifyVpcPeeringConnectionOptions( + &ec2.ModifyVpcPeeringConnectionOptionsInput{ + VpcPeeringConnectionId: connection.VpcPeeringConnectionId, + AccepterPeeringConnectionOptions: &ec2.PeeringConnectionOptionsRequest{ + AllowDnsResolutionFromRemoteVpc: aws.Bool(false), + }, + }) + if err != nil { + return err + } + return nil + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + if os.Getenv("AWS_ACCOUNT_ID") == "" { + t.Fatal("AWS_ACCOUNT_ID must be set") + } + }, + + IDRefreshName: "aws_vpc_peering_connection.foo", + IDRefreshIgnore: []string{"auto_accept"}, + + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSVpcPeeringConnectionDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccVpcPeeringConfigOptions, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSVpcPeeringConnectionExists( + "aws_vpc_peering_connection.foo", + &connection), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "accepter.#", "1"), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "accepter.0.allow_remote_vpc_dns_resolution", "true"), + testAccCheckAWSVpcPeeringConnectionOptions( + "aws_vpc_peering_connection.foo", "accepter", + &ec2.VpcPeeringConnectionOptionsDescription{ + AllowDnsResolutionFromRemoteVpc: aws.Bool(true), + AllowEgressFromLocalClassicLinkToRemoteVpc: aws.Bool(false), + AllowEgressFromLocalVpcToRemoteClassicLink: aws.Bool(false), + }), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "requester.#", "1"), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "requester.0.allow_classic_link_to_remote_vpc", "true"), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "requester.0.allow_vpc_to_remote_classic_link", "true"), + testAccCheckAWSVpcPeeringConnectionOptions( + "aws_vpc_peering_connection.foo", "requester", + &ec2.VpcPeeringConnectionOptionsDescription{ + AllowDnsResolutionFromRemoteVpc: aws.Bool(false), + AllowEgressFromLocalClassicLinkToRemoteVpc: aws.Bool(true), + AllowEgressFromLocalVpcToRemoteClassicLink: aws.Bool(true), + }, + ), + testAccepterChange, + ), + ExpectNonEmptyPlan: true, + }, + resource.TestStep{ + Config: testAccVpcPeeringConfigOptions, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSVpcPeeringConnectionExists( + "aws_vpc_peering_connection.foo", + &connection), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "accepter.#", "1"), + resource.TestCheckResourceAttr( + "aws_vpc_peering_connection.foo", + "accepter.0.allow_remote_vpc_dns_resolution", "true"), + testAccCheckAWSVpcPeeringConnectionOptions( + "aws_vpc_peering_connection.foo", "accepter", + &ec2.VpcPeeringConnectionOptionsDescription{ + AllowDnsResolutionFromRemoteVpc: aws.Bool(true), + AllowEgressFromLocalClassicLinkToRemoteVpc: aws.Bool(false), + AllowEgressFromLocalVpcToRemoteClassicLink: aws.Bool(false), + }, + ), + ), + }, + }, + }) +} + func testAccCheckAWSVpcPeeringConnectionDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -138,12 +245,12 @@ func testAccCheckAWSVpcPeeringConnectionDestroy(s *terraform.State) error { if *pc.Status.Code == "deleted" { return nil } - return fmt.Errorf("Found vpc peering connection in unexpected state: %s", pc) + return fmt.Errorf("Found the VPC Peering Connection in an unexpected state: %s", pc) } // return error here; we've found the vpc_peering object we want, however // it's not in an expected state - return fmt.Errorf("Fall through error for testAccCheckAWSVpcPeeringConnectionDestroy") + return fmt.Errorf("Fall through error for testAccCheckAWSVpcPeeringConnectionDestroy.") } return nil @@ -157,7 +264,7 @@ func testAccCheckAWSVpcPeeringConnectionExists(n string, connection *ec2.VpcPeer } if rs.Primary.ID == "" { - return fmt.Errorf("No vpc peering connection id is set") + return fmt.Errorf("No VPC Peering Connection ID is set.") } conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -169,7 +276,7 @@ func testAccCheckAWSVpcPeeringConnectionExists(n string, connection *ec2.VpcPeer return err } if len(resp.VpcPeeringConnections) == 0 { - return fmt.Errorf("VPC peering connection not found") + return fmt.Errorf("VPC Peering Connection could not be found.") } *connection = *resp.VpcPeeringConnections[0] @@ -178,43 +285,105 @@ func testAccCheckAWSVpcPeeringConnectionExists(n string, connection *ec2.VpcPeer } } +func testAccCheckAWSVpcPeeringConnectionOptions(n, block string, options *ec2.VpcPeeringConnectionOptionsDescription) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No VPC Peering Connection ID is set.") + } + + conn := testAccProvider.Meta().(*AWSClient).ec2conn + resp, err := conn.DescribeVpcPeeringConnections( + &ec2.DescribeVpcPeeringConnectionsInput{ + VpcPeeringConnectionIds: []*string{aws.String(rs.Primary.ID)}, + }) + if err != nil { + return err + } + + pc := resp.VpcPeeringConnections[0] + + o := pc.AccepterVpcInfo + if block == "requester" { + o = pc.RequesterVpcInfo + } + + if !reflect.DeepEqual(o.PeeringOptions, options) { + return fmt.Errorf("Expected the VPC Peering Connection Options to be %#v, got %#v", + options, o.PeeringOptions) + } + + return nil + } +} + const testAccVpcPeeringConfig = ` resource "aws_vpc" "foo" { - cidr_block = "10.0.0.0/16" - tags { - Name = "TestAccAWSVPCPeeringConnection_basic" - } + cidr_block = "10.0.0.0/16" + tags { + Name = "TestAccAWSVPCPeeringConnection_basic" + } } resource "aws_vpc" "bar" { - cidr_block = "10.1.0.0/16" + cidr_block = "10.1.0.0/16" } resource "aws_vpc_peering_connection" "foo" { - vpc_id = "${aws_vpc.foo.id}" - peer_vpc_id = "${aws_vpc.bar.id}" - auto_accept = true + vpc_id = "${aws_vpc.foo.id}" + peer_vpc_id = "${aws_vpc.bar.id}" + auto_accept = true } ` const testAccVpcPeeringConfigTags = ` resource "aws_vpc" "foo" { - cidr_block = "10.0.0.0/16" - tags { - Name = "TestAccAWSVPCPeeringConnection_tags" - } + cidr_block = "10.0.0.0/16" + tags { + Name = "TestAccAWSVPCPeeringConnection_tags" + } } resource "aws_vpc" "bar" { - cidr_block = "10.1.0.0/16" + cidr_block = "10.1.0.0/16" } resource "aws_vpc_peering_connection" "foo" { - vpc_id = "${aws_vpc.foo.id}" - peer_vpc_id = "${aws_vpc.bar.id}" - peer_owner_id = "%s" - tags { - foo = "bar" - } + vpc_id = "${aws_vpc.foo.id}" + peer_vpc_id = "${aws_vpc.bar.id}" + peer_owner_id = "%s" + tags { + foo = "bar" + } +} +` + +const testAccVpcPeeringConfigOptions = ` +resource "aws_vpc" "foo" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_vpc" "bar" { + cidr_block = "10.1.0.0/16" + enable_dns_hostnames = true +} + +resource "aws_vpc_peering_connection" "foo" { + vpc_id = "${aws_vpc.foo.id}" + peer_vpc_id = "${aws_vpc.bar.id}" + auto_accept = true + + accepter { + allow_remote_vpc_dns_resolution = true + } + + requester { + allow_vpc_to_remote_classic_link = true + allow_classic_link_to_remote_vpc = true + } } ` diff --git a/website/source/docs/providers/aws/r/vpc_peering.html.markdown b/website/source/docs/providers/aws/r/vpc_peering.html.markdown index c083591f4a91..82b94cdd7431 100644 --- a/website/source/docs/providers/aws/r/vpc_peering.html.markdown +++ b/website/source/docs/providers/aws/r/vpc_peering.html.markdown @@ -22,6 +22,24 @@ resource "aws_vpc_peering_connection" "foo" { } ``` +Basic usage with connection options: + +``` +resource "aws_vpc_peering_connection" "foo" { + peer_owner_id = "${var.peer_owner_id}" + peer_vpc_id = "${aws_vpc.bar.id}" + vpc_id = "${aws_vpc.foo.id}" + + accepter { + allow_remote_vpc_dns_resolution = true + } + + requester { + allow_remote_vpc_dns_resolution = true + } +} +``` + Basic usage with tags: ``` @@ -30,10 +48,11 @@ resource "aws_vpc_peering_connection" "foo" { peer_owner_id = "${var.peer_owner_id}" peer_vpc_id = "${aws_vpc.bar.id}" vpc_id = "${aws_vpc.foo.id}" - + auto_accept = true - tags { - Name = "VPC Peering between foo and bar" + + tags { + Name = "VPC Peering between foo and bar" } } @@ -51,26 +70,51 @@ resource "aws_vpc" "bar" { The following arguments are supported: * `peer_owner_id` - (Required) The AWS account ID of the owner of the peer VPC. -* `peer_vpc_id` - (Required) The ID of the VPC with which you are creating the VPC peering connection. +* `peer_vpc_id` - (Required) The ID of the VPC with which you are creating the VPC Peering Connection. * `vpc_id` - (Required) The ID of the requester VPC. * `auto_accept` - (Optional) Accept the peering (you need to be the owner of both VPCs). +* `accepter` (Optional) - An optional configuration block that allows for [VPC Peering Connection] +(http://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide) options to be set for the VPC that accepts +the peering connection (a maximum of one). +* `requester` (Optional) - A optional configuration block that allows for [VPC Peering Connection] +(http://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide) options to be set for the VPC that requests +the peering connection (a maximum of one). * `tags` - (Optional) A mapping of tags to assign to the resource. +#### Accepter and Requester Arguments + +-> **Note:** When enabled, the DNS resolution feature requires that VPCs participating in the peering +must have support for the DNS hostnames enabled. This can be done using the [`enable_dns_hostnames`] +(vpc.html#enable_dns_hostnames) attribute in the [`aws_vpc`](vpc.html) resource. See [Using DNS with Your VPC] +(http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-dns.html) user guide for more information. + +* `allow_remote_vpc_dns_resolution` - (Optional) Allow a local VPC to resolve public DNS hostnames to private +IP addresses when queried from instances in the peer VPC. +* `allow_classic_link_to_remote_vpc` - (Optional) Allow a local linked EC2-Classic instance to communicate +with instances in a peer VPC. This enables an outbound communication from the local ClassicLink connection +to the remote VPC. +* `allow_vpc_to_remote_classic_link` - (Optional) Allow a local VPC to communicate with a linked EC2-Classic +instance in a peer VPC. This enables an outbound communication from the local VPC to the remote ClassicLink +connection. + ## Attributes Reference The following attributes are exported: -* `id` - The ID of the VPC Peering Connections -* `accept_status` - The Status of the VPC peering connection request. +* `id` - The ID of the VPC Peering Connection. +* `accept_status` - The status of the VPC Peering Connection request. ## Notes -If you are not the owner of both VPCs, or do not enable auto_accept you will still have to accept the peering with the AWS Console, aws-cli or aws-sdk-go. + +If you are not the owner of both VPCs, or do not enable the `auto_accept` attribute you will still +have to accept the VPC Peering Connection request manually using the AWS Management Console, AWS CLI, +through SDKs, etc. ## Import -VPC Peering resources can be imported using the `vpc peering id`, e.g. +VPC Peering resources can be imported using the `vpc peering id`, e.g. ``` $ terraform import aws_vpc_peering_connection.test_connection pcx-111aaa111 -``` \ No newline at end of file +``` From b5a44dec584a0ec0024820f4cb7d29fcb174ed29 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Fri, 19 Aug 2016 11:21:21 +0100 Subject: [PATCH 031/100] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35f885482e45..308dd4196276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ IMPROVEMENTS * provider/aws: Add `force_destroy` option to `aws_route53_zone` [GH-8239] * provider/aws: Support import of `aws_s3_bucket` [GH-8262] * provider/aws: Increase timeout for retrying creation of IAM role [GH-7733] + * provider/aws: Add ability to set peering options in aws_vpc_peering_connection. [GH-8310] * provider/azure: add custom_data argument for azure_instance resource [GH-8158] * provider/azurerm: Adds support for uploading blobs to azure storage from local source [GH-7994] * provider/azurerm: Storage blob contents can be copied from an existing blob [GH-8126] From da5abccfd9184af08c2d02ec64cb5b4f54b2f2a3 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 19 Aug 2016 13:00:45 +0100 Subject: [PATCH 032/100] provider/aws: Implement support for CloudWatch Metric in `aws_route53_health_check` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #7830 ``` % make testacc TEST=./builtin/providers/aws % TESTARGS='-run=TestAccAWSRoute53HealthCheck_' ✚ ==> Checking that code complies with gofmt requirements... /Users/stacko/Code/go/bin/stringer go generate $(go list ./... | grep -v /terraform/vendor/) 2016/08/19 12:58:00 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSRoute53HealthCheck_ -timeout 120m === RUN TestAccAWSRoute53HealthCheck_importBasic --- PASS: TestAccAWSRoute53HealthCheck_importBasic (20.03s) === RUN TestAccAWSRoute53HealthCheck_basic --- PASS: TestAccAWSRoute53HealthCheck_basic (31.42s) === RUN TestAccAWSRoute53HealthCheck_withChildHealthChecks --- PASS: TestAccAWSRoute53HealthCheck_withChildHealthChecks (26.88s) === RUN TestAccAWSRoute53HealthCheck_IpConfig --- PASS: TestAccAWSRoute53HealthCheck_IpConfig (30.27s) === RUN TestAccAWSRoute53HealthCheck_CloudWatchAlarmCheck --- PASS: TestAccAWSRoute53HealthCheck_CloudWatchAlarmCheck (26.08s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 134.692s ``` --- .../aws/resource_aws_route53_health_check.go | 55 ++++++++++++++++++- .../resource_aws_route53_health_check_test.go | 39 +++++++++++++ .../aws/r/route53_health_check.html.markdown | 29 +++++++++- 3 files changed, 121 insertions(+), 2 deletions(-) diff --git a/builtin/providers/aws/resource_aws_route53_health_check.go b/builtin/providers/aws/resource_aws_route53_health_check.go index 0c16770ae131..e9d2e3d2252b 100644 --- a/builtin/providers/aws/resource_aws_route53_health_check.go +++ b/builtin/providers/aws/resource_aws_route53_health_check.go @@ -69,6 +69,7 @@ func resourceAwsRoute53HealthCheck() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "measure_latency": &schema.Schema{ Type: schema.TypeBool, Optional: true, @@ -95,6 +96,21 @@ func resourceAwsRoute53HealthCheck() *schema.Resource { }, }, + "cloudwatch_alarm_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "cloudwatch_alarm_region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "insufficient_data_health_status": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": tagsSchema(), }, } @@ -135,6 +151,19 @@ func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{ updateHealthCheck.HealthThreshold = aws.Int64(int64(d.Get("child_health_threshold").(int))) } + if d.HasChange("cloudwatch_alarm_name") || d.HasChange("cloudwatch_alarm_region") { + cloudwatchAlarm := &route53.AlarmIdentifier{ + Name: aws.String(d.Get("cloudwatch_alarm_name").(string)), + Region: aws.String(d.Get("cloudwatch_alarm_region").(string)), + } + + updateHealthCheck.AlarmIdentifier = cloudwatchAlarm + } + + if d.HasChange("insufficient_data_health_status") { + updateHealthCheck.InsufficientDataHealthStatus = aws.String(d.Get("insufficient_data_health_status").(string)) + } + _, err := conn.UpdateHealthCheck(updateHealthCheck) if err != nil { return err @@ -182,7 +211,7 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{ healthConfig.ResourcePath = aws.String(v.(string)) } - if *healthConfig.Type != route53.HealthCheckTypeCalculated { + if *healthConfig.Type != route53.HealthCheckTypeCalculated && *healthConfig.Type != route53.HealthCheckTypeCloudwatchMetric { if v, ok := d.GetOk("measure_latency"); ok { healthConfig.MeasureLatency = aws.Bool(v.(bool)) } @@ -202,6 +231,24 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{ } } + if *healthConfig.Type == route53.HealthCheckTypeCloudwatchMetric { + cloudwatchAlarmIdentifier := &route53.AlarmIdentifier{} + + if v, ok := d.GetOk("cloudwatch_alarm_name"); ok { + cloudwatchAlarmIdentifier.Name = aws.String(v.(string)) + } + + if v, ok := d.GetOk("cloudwatch_alarm_region"); ok { + cloudwatchAlarmIdentifier.Region = aws.String(v.(string)) + } + + healthConfig.AlarmIdentifier = cloudwatchAlarmIdentifier + + if v, ok := d.GetOk("insufficient_data_health_status"); ok { + healthConfig.InsufficientDataHealthStatus = aws.String(v.(string)) + } + } + input := &route53.CreateHealthCheckInput{ CallerReference: aws.String(time.Now().Format(time.RFC3339Nano)), HealthCheckConfig: healthConfig, @@ -252,6 +299,12 @@ func resourceAwsRoute53HealthCheckRead(d *schema.ResourceData, meta interface{}) d.Set("invert_healthcheck", updated.Inverted) d.Set("child_healthchecks", updated.ChildHealthChecks) d.Set("child_health_threshold", updated.HealthThreshold) + d.Set("insufficient_data_health_status", updated.InsufficientDataHealthStatus) + + if updated.AlarmIdentifier != nil { + d.Set("cloudwatch_alarm_name", updated.AlarmIdentifier.Name) + d.Set("cloudwatch_alarm_region", updated.AlarmIdentifier.Region) + } // read the tags req := &route53.ListTagsForResourceInput{ diff --git a/builtin/providers/aws/resource_aws_route53_health_check_test.go b/builtin/providers/aws/resource_aws_route53_health_check_test.go index 9792ac10fd0f..e18965546809 100644 --- a/builtin/providers/aws/resource_aws_route53_health_check_test.go +++ b/builtin/providers/aws/resource_aws_route53_health_check_test.go @@ -73,6 +73,24 @@ func TestAccAWSRoute53HealthCheck_IpConfig(t *testing.T) { }) } +func TestAccAWSRoute53HealthCheck_CloudWatchAlarmCheck(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53HealthCheckDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRoute53HealthCheckCloudWatchAlarm, + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53HealthCheckExists("aws_route53_health_check.foo"), + resource.TestCheckResourceAttr( + "aws_route53_health_check.foo", "cloudwatch_alarm_name", "cloudwatch-healthcheck-alarm"), + ), + }, + }, + }) +} + func testAccCheckRoute53HealthCheckDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).r53conn @@ -208,3 +226,24 @@ resource "aws_route53_health_check" "foo" { } } ` + +const testAccRoute53HealthCheckCloudWatchAlarm = ` +resource "aws_cloudwatch_metric_alarm" "foobar" { + alarm_name = "cloudwatch-healthcheck-alarm" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + period = "120" + statistic = "Average" + threshold = "80" + alarm_description = "This metric monitor ec2 cpu utilization" +} + +resource "aws_route53_health_check" "foo" { + type = "CLOUDWATCH_METRIC" + cloudwatch_alarm_name = "${aws_cloudwatch_metric_alarm.foobar.alarm_name}" + cloudwatch_alarm_region = "us-west-2" + insufficient_data_health_status = "Healthy" +} +` diff --git a/website/source/docs/providers/aws/r/route53_health_check.html.markdown b/website/source/docs/providers/aws/r/route53_health_check.html.markdown index 6d2c66a5cb61..283e978d0adb 100644 --- a/website/source/docs/providers/aws/r/route53_health_check.html.markdown +++ b/website/source/docs/providers/aws/r/route53_health_check.html.markdown @@ -36,6 +36,29 @@ resource "aws_route53_health_check" "foo" { } ``` +## CloudWatch Alarm Example + +``` +resource "aws_cloudwatch_metric_alarm" "foobar" { + alarm_name = "terraform-test-foobar5" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + period = "120" + statistic = "Average" + threshold = "80" + alarm_description = "This metric monitor ec2 cpu utilization" +} + +resource "aws_route53_health_check" "foo" { + type = "CLOUDWATCH_METRIC" + cloudwatch_alarm_name = "${aws_cloudwatch_metric_alarm.foobar.alarm_name}" + cloudwatch_alarm_region = "us-west-2" + insufficient_data_health_status = "Healthy" +} +``` + ## Argument Reference The following arguments are supported: @@ -43,7 +66,7 @@ The following arguments are supported: * `fqdn` - (Optional) The fully qualified domain name of the endpoint to be checked. * `ip_address` - (Optional) The IP address of the endpoint to be checked. * `port` - (Optional) The port of the endpoint to be checked. -* `type` - (Required) The protocol to use when performing health checks. Valid values are `HTTP`, `HTTPS`, `HTTP_STR_MATCH`, `HTTPS_STR_MATCH`, `TCP` and `CALCULATED`. +* `type` - (Required) The protocol to use when performing health checks. Valid values are `HTTP`, `HTTPS`, `HTTP_STR_MATCH`, `HTTPS_STR_MATCH`, `TCP`, `CALCULATED` and `CLOUDWATCH_METRIC`. * `failure_threshold` - (Required) The number of consecutive health checks that an endpoint must pass or fail. * `request_interval` - (Required) The number of seconds between the time that Amazon Route 53 gets a response from your endpoint and the time that it sends the next health-check request. * `resource_path` - (Optional) The path that you want Amazon Route 53 to request when performing health checks. @@ -52,6 +75,10 @@ The following arguments are supported: * `invert_healthcheck` - (Optional) A boolean value that indicates whether the status of health check should be inverted. For example, if a health check is healthy but Inverted is True , then Route 53 considers the health check to be unhealthy. * `child_healthchecks` - (Optional) For a specified parent health check, a list of HealthCheckId values for the associated child health checks. * `child_health_threshold` - (Optional) The minimum number of child health checks that must be healthy for Route 53 to consider the parent health check to be healthy. Valid values are integers between 0 and 256, inclusive +* `cloudwatch_alarm_name` - (Optional) The name of the CloudWatch alarm. +* `cloudwatch_alarm_region` - (Optional) The CloudWatchRegion that the CloudWatch alarm was created in. +* `insufficient_data_health_status` - (Optional) The status of the health check when CloudWatch has insufficient data about the state of associated alarm. Valid values are `Healthy` , `Unhealthy` and `LastKnownStatus`. + * `tags` - (Optional) A mapping of tags to assign to the health check. At least one of either `fqdn` or `ip_address` must be specified. From 417b98bafba8b4a528a1b91077e5f1f3e342b242 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Thu, 18 Aug 2016 23:43:11 +0100 Subject: [PATCH 033/100] provider/aws: Add aws_alb_listener_rule resource This commit adds the aws_alb_listener_rule resource along with acceptance tests and documentation. --- builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_alb_listener.go | 4 +- .../aws/resource_aws_alb_listener_rule.go | 252 ++++++++++++++++++ .../resource_aws_alb_listener_rule_test.go | 216 +++++++++++++++ .../aws/r/alb_listener_rule.html.markdown | 73 +++++ website/source/layouts/aws.erb | 4 + 6 files changed, 548 insertions(+), 2 deletions(-) create mode 100644 builtin/providers/aws/resource_aws_alb_listener_rule.go create mode 100644 builtin/providers/aws/resource_aws_alb_listener_rule_test.go create mode 100644 website/source/docs/providers/aws/r/alb_listener_rule.html.markdown diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 52382eb0307c..106ce575d248 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -154,6 +154,7 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ "aws_alb": resourceAwsAlb(), "aws_alb_listener": resourceAwsAlbListener(), + "aws_alb_listener_rule": resourceAwsAlbListenerRule(), "aws_alb_target_group": resourceAwsAlbTargetGroup(), "aws_ami": resourceAwsAmi(), "aws_ami_copy": resourceAwsAmiCopy(), diff --git a/builtin/providers/aws/resource_aws_alb_listener.go b/builtin/providers/aws/resource_aws_alb_listener.go index a2bdf2413483..5d5baac0d564 100644 --- a/builtin/providers/aws/resource_aws_alb_listener.go +++ b/builtin/providers/aws/resource_aws_alb_listener.go @@ -73,7 +73,7 @@ func resourceAwsAlbListener() *schema.Resource { "type": { Type: schema.TypeString, Required: true, - ValidateFunc: validateAwsAlbListenerDefaultActionType, + ValidateFunc: validateAwsAlbListenerActionType, }, }, }, @@ -247,7 +247,7 @@ func validateAwsAlbListenerProtocol(v interface{}, k string) (ws []string, error return } -func validateAwsAlbListenerDefaultActionType(v interface{}, k string) (ws []string, errors []error) { +func validateAwsAlbListenerActionType(v interface{}, k string) (ws []string, errors []error) { value := strings.ToLower(v.(string)) if value != "forward" { errors = append(errors, fmt.Errorf("%q must have the value %q", k, "forward")) diff --git a/builtin/providers/aws/resource_aws_alb_listener_rule.go b/builtin/providers/aws/resource_aws_alb_listener_rule.go new file mode 100644 index 000000000000..f1dc944b5a9d --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_listener_rule.go @@ -0,0 +1,252 @@ +package aws + +import ( + "errors" + "fmt" + "log" + "strconv" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsAlbListenerRule() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsAlbListenerRuleCreate, + Read: resourceAwsAlbListenerRuleRead, + Update: resourceAwsAlbListenerRuleUpdate, + Delete: resourceAwsAlbListenerRuleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "listener_arn": { + Type: schema.TypeString, + Required: true, + }, + "priority": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validateAwsAlbListenerRulePriority, + }, + "action": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target_group_arn": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAwsAlbListenerActionType, + }, + }, + }, + }, + "condition": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "field": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAwsListenerRuleField, + }, + "values": { + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, + }, + }, + }, + }, + } +} + +func resourceAwsAlbListenerRuleCreate(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.CreateRuleInput{ + ListenerArn: aws.String(d.Get("listener_arn").(string)), + Priority: aws.Int64(int64(d.Get("priority").(int))), + } + + actions := d.Get("action").([]interface{}) + params.Actions = make([]*elbv2.Action, len(actions)) + for i, action := range actions { + actionMap := action.(map[string]interface{}) + params.Actions[i] = &elbv2.Action{ + TargetGroupArn: aws.String(actionMap["target_group_arn"].(string)), + Type: aws.String(actionMap["type"].(string)), + } + } + + conditions := d.Get("condition").([]interface{}) + params.Conditions = make([]*elbv2.RuleCondition, len(conditions)) + for i, condition := range conditions { + conditionMap := condition.(map[string]interface{}) + values := conditionMap["values"].([]interface{}) + params.Conditions[i] = &elbv2.RuleCondition{ + Field: aws.String(conditionMap["field"].(string)), + Values: make([]*string, len(values)), + } + for j, value := range values { + params.Conditions[i].Values[j] = aws.String(value.(string)) + } + } + + resp, err := elbconn.CreateRule(params) + if err != nil { + return errwrap.Wrapf("Error creating ALB Listener Rule: {{err}}", err) + } + + if len(resp.Rules) == 0 { + return errors.New("Error creating ALB Listener Rule: no rules returned in response") + } + + d.SetId(*resp.Rules[0].RuleArn) + + return resourceAwsAlbListenerRuleRead(d, meta) +} + +func resourceAwsAlbListenerRuleRead(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + resp, err := elbconn.DescribeRules(&elbv2.DescribeRulesInput{ + RuleArns: []*string{aws.String(d.Id())}, + }) + if err != nil { + if isRuleNotFound(err) { + log.Printf("[WARN] DescribeRules - removing %s from state", d.Id()) + d.SetId("") + return nil + } + return errwrap.Wrapf(fmt.Sprintf("Error retrieving Rules for listener %s: {{err}}", d.Id()), err) + } + + if len(resp.Rules) != 1 { + return fmt.Errorf("Error retrieving Rule %q", d.Id()) + } + + rule := resp.Rules[0] + + d.Set("arn", rule.RuleArn) + if priority, err := strconv.Atoi(*rule.Priority); err != nil { + return errwrap.Wrapf("Cannot convert rule priority %q to int: {{err}}", err) + } else { + d.Set("priority", priority) + } + + actions := make([]interface{}, len(rule.Actions)) + for i, action := range rule.Actions { + actionMap := make(map[string]interface{}) + actionMap["target_group_arn"] = *action.TargetGroupArn + actionMap["type"] = *action.Type + actions[i] = actionMap + } + d.Set("action", actions) + + conditions := make([]interface{}, len(rule.Conditions)) + for i, condition := range rule.Conditions { + conditionMap := make(map[string]interface{}) + conditionMap["field"] = *condition.Field + conditionValues := make([]string, len(condition.Values)) + for k, value := range condition.Values { + conditionValues[k] = *value + } + conditionMap["values"] = conditionValues + conditions[i] = conditionMap + } + d.Set("condition", conditions) + + return nil +} + +func resourceAwsAlbListenerRuleUpdate(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.ModifyRuleInput{ + RuleArn: aws.String(d.Id()), + } + + actions := d.Get("action").([]interface{}) + params.Actions = make([]*elbv2.Action, len(actions)) + for i, action := range actions { + actionMap := action.(map[string]interface{}) + params.Actions[i] = &elbv2.Action{ + TargetGroupArn: aws.String(actionMap["target_group_arn"].(string)), + Type: aws.String(actionMap["type"].(string)), + } + } + + conditions := d.Get("condition").([]interface{}) + params.Conditions = make([]*elbv2.RuleCondition, len(conditions)) + for i, condition := range conditions { + conditionMap := condition.(map[string]interface{}) + values := conditionMap["values"].([]interface{}) + params.Conditions[i] = &elbv2.RuleCondition{ + Field: aws.String(conditionMap["field"].(string)), + Values: make([]*string, len(values)), + } + for j, value := range values { + params.Conditions[i].Values[j] = aws.String(value.(string)) + } + } + + resp, err := elbconn.ModifyRule(params) + if err != nil { + return errwrap.Wrapf("Error modifying ALB Listener Rule: {{err}}", err) + } + + if len(resp.Rules) == 0 { + return errors.New("Error modifying creating ALB Listener Rule: no rules returned in response") + } + + return resourceAwsAlbListenerRuleRead(d, meta) +} + +func resourceAwsAlbListenerRuleDelete(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + _, err := elbconn.DeleteRule(&elbv2.DeleteRuleInput{ + RuleArn: aws.String(d.Id()), + }) + if err != nil && !isRuleNotFound(err) { + return errwrap.Wrapf("Error deleting ALB Listener Rule: {{err}}", err) + } + return nil +} + +func validateAwsAlbListenerRulePriority(v interface{}, k string) (ws []string, errors []error) { + value := v.(int) + if value < 1 || value > 99999 { + errors = append(errors, fmt.Errorf("%q must be in the range 1-99999", k)) + } + return +} + +func validateAwsListenerRuleField(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 64 { + errors = append(errors, fmt.Errorf("%q must be a maximum of 64 characters", k)) + } + return +} + +func isRuleNotFound(err error) bool { + elberr, ok := err.(awserr.Error) + return ok && elberr.Code() == "RuleNotFound" +} diff --git a/builtin/providers/aws/resource_aws_alb_listener_rule_test.go b/builtin/providers/aws/resource_aws_alb_listener_rule_test.go new file mode 100644 index 000000000000..683fa3535b92 --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_listener_rule_test.go @@ -0,0 +1,216 @@ +package aws + +import ( + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSALBListenerRule_basic(t *testing.T) { + var conf elbv2.Rule + albName := fmt.Sprintf("testrule-basic-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + targetGroupName := fmt.Sprintf("testtargetgroup-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb_listener_rule.static", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBListenerRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBListenerRuleConfig_basic(albName, targetGroupName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBListenerRuleExists("aws_alb_listener_rule.static", &conf), + resource.TestCheckResourceAttrSet("aws_alb_listener_rule.static", "arn"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "priority", "100"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "action.#", "1"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "action.0.type", "forward"), + resource.TestCheckResourceAttrSet("aws_alb_listener_rule.static", "action.0.target_group_arn"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "condition.#", "1"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "condition.0.field", "path-pattern"), + resource.TestCheckResourceAttr("aws_alb_listener_rule.static", "condition.0.values.#", "1"), + resource.TestCheckResourceAttrSet("aws_alb_listener_rule.static", "condition.0.values.0"), + ), + }, + }, + }) +} + +func testAccCheckAWSALBListenerRuleExists(n string, res *elbv2.Rule) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("No Listener Rule ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + describe, err := conn.DescribeRules(&elbv2.DescribeRulesInput{ + RuleArns: []*string{aws.String(rs.Primary.ID)}, + }) + + if err != nil { + return err + } + + if len(describe.Rules) != 1 || + *describe.Rules[0].RuleArn != rs.Primary.ID { + return errors.New("Listener Rule not found") + } + + *res = *describe.Rules[0] + return nil + } +} + +func testAccCheckAWSALBListenerRuleDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_alb_listener_rule" { + continue + } + + describe, err := conn.DescribeRules(&elbv2.DescribeRulesInput{ + RuleArns: []*string{aws.String(rs.Primary.ID)}, + }) + + if err == nil { + if len(describe.Rules) != 0 && + *describe.Rules[0].RuleArn == rs.Primary.ID { + return fmt.Errorf("Listener Rule %q still exists", rs.Primary.ID) + } + } + + // Verify the error + if isRuleNotFound(err) { + return nil + } else { + return errwrap.Wrapf("Unexpected error checking ALB Listener Rule destroyed: {{err}}", err) + } + } + + return nil +} + +func testAccAWSALBListenerRuleConfig_basic(albName, targetGroupName string) string { + return fmt.Sprintf(`resource "aws_alb_listener_rule" "static" { + listener_arn = "${aws_alb_listener.front_end.arn}" + priority = 100 + + action { + type = "forward" + target_group_arn = "${aws_alb_target_group.test.arn}" + } + + condition { + field = "path-pattern" + values = ["/static/*"] + } +} + +resource "aws_alb_listener" "front_end" { + load_balancer_arn = "${aws_alb.alb_test.id}" + protocol = "HTTP" + port = "80" + + default_action { + target_group_arn = "${aws_alb_target_group.test.id}" + type = "forward" + } +} + +resource "aws_alb" "alb_test" { + name = "%s" + internal = false + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_alb_target_group" "test" { + name = "%s" + port = 8080 + protocol = "HTTP" + vpc_id = "${aws_vpc.alb_test.id}" + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + TestName = "TestAccAWSALB_basic" + } +}`, albName, targetGroupName) +} diff --git a/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown b/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown new file mode 100644 index 000000000000..84054ad3c259 --- /dev/null +++ b/website/source/docs/providers/aws/r/alb_listener_rule.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "aws" +page_title: "AWS: aws_alb_listener_rule" +sidebar_current: "docs-aws-resource-alb-listener-rule" +description: |- + Provides an Application Load Balancer Listener Rule resource. +--- + +# aws\_alb\_listener\_rule + +Provides an Application Load Balancer Listener Rule resource. + +## Example Usage + +``` +# Create a new load balancer +resource "aws_alb" "front_end" { + # Other parameters... +} + +resource "aws_alb_listener" "front_end" { + # Other parameters +} + +resource "aws_alb_listener_rule" "static" { + listener_arn = "${aws_alb_listener.front_end.arn} + priority = 100 + + action { + type = "forward" + target_group_arn = "${aws_alb_target_group.static.arn}" + } + + condition { + field = "path-pattern" + values = ["/static/*"] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `listener_arn` - (Required, Forces New Resource) The ARN of the listener to which to attach the rule. +* `priority` - (Required) The priority for the rule. A listener can't have multiple rules with the same priority. +* `action` - (Required) An Action block. Action blocks are documented below. +* `condition` - (Required) A Condition block. Condition blocks are documented below. + +Action Blocks (for `default_action`) support the following: + +* `target_group_arn` - (Required) The ARN of the Target Group to which to route traffic. +* `type` - (Required) The type of routing action. The only valid value is `forward`. + +Condition Blocks (for `default_action`) support the following: + +* `field` - (Required) The name of the field. The only valid value is `path-pattern`. +* `values` - (Required) The path patterns to match. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ARN of the rule (matches `arn`) +* `arn` - The ARN of the rule (matches `id`) + +## Import + +Rules can be imported using their ARN, e.g. + +``` +$ terraform import aws_alb_listener_rule.front_end arn:aws:elasticloadbalancing:us-west-2:187416307283:listener-rule/app/test/8e4497da625e2d8a/9ab28ade35828f96/67b3d2d36dd7c26b +``` diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 9b7731fd5be7..b88b462b7b54 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -218,6 +218,10 @@ aws_alb_listener + > + aws_alb_listener_rule + + > aws_alb_target_group From 0800bc269f2c78ed34287bc61d47c3a44ed6cffc Mon Sep 17 00:00:00 2001 From: James Nugent Date: Fri, 19 Aug 2016 13:13:19 +0100 Subject: [PATCH 034/100] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 308dd4196276..7da069de42fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ FEATURES: IMPROVEMENTS * provider/archive support folders in output_path [GH-8278] * provider/aws: Introduce `aws_elasticsearch_domain` `elasticsearch_version` field (to specify ES version) [GH-7860] + * provider/aws: CloudWatch Metrics are now supported for `aws_route53_health_check` resources [GH-8319] * provider/aws: Query all pages of group membership [GH-6726] * provider/aws: Query all pages of IAM Policy attachments [GH-7779] * provider/aws: Change the way ARNs are built [GH-7151] From 6a2e568063f1b474314d8d30433b171e2215be26 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Fri, 19 Aug 2016 13:33:40 +0100 Subject: [PATCH 035/100] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da069de42fc..00f5482858eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ FEATURES: * **New Resource:** `aws_alb` [GH-8254] * **New Resource:** `aws_alb_listener` [GH-8269] * **New Resource:** `aws_alb_target_group` [GH-8254] + * **New Resource:** `aws_alb_target_group_rule` [GH-8318] * **New Resource:** `aws_vpn_gateway_attachment` [GH-7870] * **New Resource:** `aws_load_balancer_policy` [GH-7458] * **New Resource:** `aws_load_balancer_backend_server_policy` [GH-7458] From e4ce708bf927969377ec3a334ee0e7841a110f7a Mon Sep 17 00:00:00 2001 From: James Nugent Date: Fri, 19 Aug 2016 16:12:19 +0100 Subject: [PATCH 036/100] provider/aws: Add aws_alb_target_group_attachment --- builtin/providers/aws/provider.go | 1 + ...esource_aws_alb_target_group_attachment.go | 131 +++++++++++++++ ...ce_aws_alb_target_group_attachment_test.go | 154 ++++++++++++++++++ .../alb_target_group_attachment.html.markdown | 50 ++++++ website/source/layouts/aws.erb | 4 + 5 files changed, 340 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_alb_target_group_attachment.go create mode 100644 builtin/providers/aws/resource_aws_alb_target_group_attachment_test.go create mode 100644 website/source/docs/providers/aws/r/alb_target_group_attachment.html.markdown diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 106ce575d248..35c082c8411e 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -156,6 +156,7 @@ func Provider() terraform.ResourceProvider { "aws_alb_listener": resourceAwsAlbListener(), "aws_alb_listener_rule": resourceAwsAlbListenerRule(), "aws_alb_target_group": resourceAwsAlbTargetGroup(), + "aws_alb_target_group_attachment": resourceAwsAlbTargetGroupAttachment(), "aws_ami": resourceAwsAmi(), "aws_ami_copy": resourceAwsAmiCopy(), "aws_ami_from_instance": resourceAwsAmiFromInstance(), diff --git a/builtin/providers/aws/resource_aws_alb_target_group_attachment.go b/builtin/providers/aws/resource_aws_alb_target_group_attachment.go new file mode 100644 index 000000000000..e6ba35b94c31 --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_target_group_attachment.go @@ -0,0 +1,131 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsAlbTargetGroupAttachment() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsAlbAttachmentCreate, + Read: resourceAwsAlbAttachmentRead, + Delete: resourceAwsAlbAttachmentDelete, + + Schema: map[string]*schema.Schema{ + "target_group_arn": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + + "target_id": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + + "port": { + Type: schema.TypeInt, + ForceNew: true, + Required: true, + }, + }, + } +} + +func resourceAwsAlbAttachmentCreate(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.RegisterTargetsInput{ + TargetGroupArn: aws.String(d.Get("target_group_arn").(string)), + Targets: []*elbv2.TargetDescription{ + { + Id: aws.String(d.Get("target_id").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + }, + }, + } + + log.Printf("[INFO] Registering Target %s (%d) with Target Group %s", d.Get("target_id").(string), + d.Get("port").(int), d.Get("target_group_arn").(string)) + + _, err := elbconn.RegisterTargets(params) + if err != nil { + return errwrap.Wrapf("Error registering targets with target group: {{err}}", err) + } + + d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", d.Get("target_group_arn")))) + + return nil +} + +func resourceAwsAlbAttachmentDelete(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + + params := &elbv2.DeregisterTargetsInput{ + TargetGroupArn: aws.String(d.Get("target_group_arn").(string)), + Targets: []*elbv2.TargetDescription{ + { + Id: aws.String(d.Get("target_id").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + }, + }, + } + + _, err := elbconn.DeregisterTargets(params) + if err != nil && !isTargetGroupNotFound(err) { + return errwrap.Wrapf("Error deregistering Targets: {{err}}", err) + } + + d.SetId("") + + return nil +} + +// resourceAwsAlbAttachmentRead requires all of the fields in order to describe the correct +// target, so there is no work to do beyond ensuring that the target and group still exist. +func resourceAwsAlbAttachmentRead(d *schema.ResourceData, meta interface{}) error { + elbconn := meta.(*AWSClient).elbv2conn + resp, err := elbconn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{ + TargetGroupArn: aws.String(d.Get("target_group_arn").(string)), + Targets: []*elbv2.TargetDescription{ + { + Id: aws.String(d.Get("target_id").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + }, + }, + }) + if err != nil { + if isTargetGroupNotFound(err) { + log.Printf("[WARN] Target group does not exist, removing target attachment %s", d.Id()) + d.SetId("") + return nil + } + if isInvalidTarget(err) { + log.Printf("[WARN] Target does not exist, removing target attachment %s", d.Id()) + d.SetId("") + return nil + } + return errwrap.Wrapf("Error reading Target Health: {{err}}", err) + } + + if len(resp.TargetHealthDescriptions) != 1 { + log.Printf("[WARN] Target does not exist, removing target attachment %s", d.Id()) + d.SetId("") + return nil + } + + return nil +} + +func isInvalidTarget(err error) bool { + elberr, ok := err.(awserr.Error) + return ok && elberr.Code() == "InvalidTarget" +} diff --git a/builtin/providers/aws/resource_aws_alb_target_group_attachment_test.go b/builtin/providers/aws/resource_aws_alb_target_group_attachment_test.go new file mode 100644 index 000000000000..bd063516db21 --- /dev/null +++ b/builtin/providers/aws/resource_aws_alb_target_group_attachment_test.go @@ -0,0 +1,154 @@ +package aws + +import ( + "errors" + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "strconv" + "testing" +) + +func TestAccAWSALBTargetGroupAttachment_basic(t *testing.T) { + targetGroupName := fmt.Sprintf("test-target-group-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb_target_group.test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBTargetGroupAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBTargetGroupAttachmentConfig_basic(targetGroupName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBTargetGroupAttachmentExists("aws_alb_target_group_attachment.test"), + ), + }, + }, + }) +} + +func testAccCheckAWSALBTargetGroupAttachmentExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return errors.New("No Target Group Attachment ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + port, _ := strconv.Atoi(rs.Primary.Attributes["port"]) + describe, err := conn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{ + TargetGroupArn: aws.String(rs.Primary.Attributes["target_group_arn"]), + Targets: []*elbv2.TargetDescription{ + { + Id: aws.String(rs.Primary.Attributes["target_id"]), + Port: aws.Int64(int64(port)), + }, + }, + }) + + if err != nil { + return err + } + + if len(describe.TargetHealthDescriptions) != 1 { + return errors.New("Target Group Attachment not found") + } + + return nil + } +} + +func testAccCheckAWSALBTargetGroupAttachmentDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).elbv2conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_alb_target_group_attachment" { + continue + } + + port, _ := strconv.Atoi(rs.Primary.Attributes["port"]) + describe, err := conn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{ + TargetGroupArn: aws.String(rs.Primary.Attributes["target_group_arn"]), + Targets: []*elbv2.TargetDescription{ + { + Id: aws.String(rs.Primary.Attributes["target_id"]), + Port: aws.Int64(int64(port)), + }, + }, + }) + if err == nil { + if len(describe.TargetHealthDescriptions) != 0 { + return fmt.Errorf("Target Group Attachment %q still exists", rs.Primary.ID) + } + } + + // Verify the error + if isTargetGroupNotFound(err) || isInvalidTarget(err) { + return nil + } else { + return errwrap.Wrapf("Unexpected error checking ALB destroyed: {{err}}", err) + } + } + + return nil +} + +func testAccAWSALBTargetGroupAttachmentConfig_basic(targetGroupName string) string { + return fmt.Sprintf(` +resource "aws_alb_target_group_attachment" "test" { + target_group_arn = "${aws_alb_target_group.test.arn}" + target_id = "${aws_instance.test.id}" + port = 80 +} + +resource "aws_instance" "test" { + ami = "ami-f701cb97" + instance_type = "t2.micro" + subnet_id = "${aws_subnet.subnet.id}" +} + +resource "aws_alb_target_group" "test" { + name = "%s" + port = 443 + protocol = "HTTPS" + vpc_id = "${aws_vpc.test.id}" + + deregistration_delay = 200 + + stickiness { + type = "lb_cookie" + cookie_duration = 10000 + } + + health_check { + path = "/health" + interval = 60 + port = 8081 + protocol = "HTTP" + timeout = 3 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-299" + } +} + +resource "aws_subnet" "subnet" { + cidr_block = "10.0.1.0/24" + vpc_id = "${aws_vpc.test.id}" + +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" +}`, targetGroupName) +} diff --git a/website/source/docs/providers/aws/r/alb_target_group_attachment.html.markdown b/website/source/docs/providers/aws/r/alb_target_group_attachment.html.markdown new file mode 100644 index 000000000000..d381d6932032 --- /dev/null +++ b/website/source/docs/providers/aws/r/alb_target_group_attachment.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "aws" +page_title: "AWS: aws_alb_target_group_attachment" +sidebar_current: "docs-aws-resource-alb-target-group-attachment" +description: |- + Provides the ability to register instances and containers with an ALB + target group +--- + +# aws\_alb\_target\_group\_attachment + +Provides the ability to register instances and containers with an ALB +target group + +## Example Usage + +``` +resource "aws_alb_target_group_attachment" "test" { + target_group_arn = "${aws_alb_target_group.test.arn}" + target_id = "${aws_instance.test.id}" + port = 80 +} + +resource "aws_alb_target_group" "test" { + // Other arguments +} + +resource "aws_instance" "test" { + // Other arguments +} +``` + +## Argument Reference + +The following arguments are supported: + +* `target_group_arn` - (Required) The ARN of the target group with which to register targets +* `target_id` (Required) The ID of the target. This is the Instance ID for an instance, or the container ID for an ECS container. +* `port` - (Required) The port on which targets receive traffic. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - A unique identifier for the attachment + +## Import + +Target Group Attachments cannot be imported. + diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index b88b462b7b54..728d652ef3cf 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -226,6 +226,10 @@ aws_alb_target_group + > + aws_alb_target_group_attachment + + > aws_ami From bd25d77615aedfc43db46e6d0e4783b2fd1c81e8 Mon Sep 17 00:00:00 2001 From: Anastas Dancha Date: Fri, 19 Aug 2016 11:12:56 -0400 Subject: [PATCH 037/100] health_check's target explained --- website/source/docs/providers/aws/r/elb.html.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/source/docs/providers/aws/r/elb.html.markdown b/website/source/docs/providers/aws/r/elb.html.markdown index 2504d803f1ba..033b2a6218ec 100644 --- a/website/source/docs/providers/aws/r/elb.html.markdown +++ b/website/source/docs/providers/aws/r/elb.html.markdown @@ -109,7 +109,10 @@ Health Check (`health_check`) supports the following: * `healthy_threshold` - (Required) The number of checks before the instance is declared healthy. * `unhealthy_threshold` - (Required) The number of checks before the instance is declared unhealthy. -* `target` - (Required) The target of the check. +* `target` - (Required) The target of the check. Valid pattern is "${PROTOCOL}:${PORT}${PATH}", where PROTOCOL + values are: + * `HTTP`, `HTTPS` - PORT and PATH are required + * `TCP`, `SSL` - PORT is required, PATH is not supported * `interval` - (Required) The interval between checks. * `timeout` - (Required) The length of time before the check times out. From 3af67964dcf479408a7c52f9a35d34966f900bdd Mon Sep 17 00:00:00 2001 From: James Nugent Date: Fri, 19 Aug 2016 16:27:27 +0100 Subject: [PATCH 038/100] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f5482858eb..3883cf550727 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ FEATURES: * **New Resource:** `aws_alb` [GH-8254] * **New Resource:** `aws_alb_listener` [GH-8269] * **New Resource:** `aws_alb_target_group` [GH-8254] - * **New Resource:** `aws_alb_target_group_rule` [GH-8318] + * **New Resource:** `aws_alb_target_group_attachment` [GH-8254] + * **New Resource:** `aws_alb_target_group_rule` [GH-8321] * **New Resource:** `aws_vpn_gateway_attachment` [GH-7870] * **New Resource:** `aws_load_balancer_policy` [GH-7458] * **New Resource:** `aws_load_balancer_backend_server_policy` [GH-7458] From 4454d534fc2398db654b8729b95e3879003b7cef Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 11:41:00 -0400 Subject: [PATCH 039/100] terraform: test for querying count resources --- terraform/state_filter_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/terraform/state_filter_test.go b/terraform/state_filter_test.go index 55a8baeb7dd7..a0dcba0fea7a 100644 --- a/terraform/state_filter_test.go +++ b/terraform/state_filter_test.go @@ -93,6 +93,19 @@ func TestStateFilterFilter(t *testing.T) { }, }, + "no count index": { + "complete.tfstate", + []string{"module.consul.aws_instance.consul-green"}, + []string{ + "*terraform.ResourceState: module.consul.aws_instance.consul-green[0]", + "*terraform.InstanceState: module.consul.aws_instance.consul-green[0]", + "*terraform.ResourceState: module.consul.aws_instance.consul-green[1]", + "*terraform.InstanceState: module.consul.aws_instance.consul-green[1]", + "*terraform.ResourceState: module.consul.aws_instance.consul-green[2]", + "*terraform.InstanceState: module.consul.aws_instance.consul-green[2]", + }, + }, + "nested modules": { "nested-modules.tfstate", []string{"module.outer"}, From a22f7e82571927019c58f367b609347385743a82 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 11:46:52 -0400 Subject: [PATCH 040/100] terraform: State.Add works with multiple resources [GH-7797] --- terraform/state_add.go | 24 ++++++++++++++++++++ terraform/state_add_test.go | 45 +++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/terraform/state_add.go b/terraform/state_add.go index 5aa795748489..f78d293a70ec 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -151,6 +151,28 @@ func stateAddFunc_Resource_Module( } func stateAddFunc_Resource_Resource(s *State, fromAddr, addr *ResourceAddress, raw interface{}) error { + // raw can be either *ResourceState or []*ResourceState. The former means + // we're moving just one resource. The latter means we're moving a count + // of resources. + if list, ok := raw.([]*ResourceState); ok { + // We need at least one item + if len(list) == 0 { + return fmt.Errorf("resource move with no value to: %s", addr) + } + + // Add each with a specific index + for i, rs := range list { + addrCopy := addr.Copy() + addrCopy.Index = i + + if err := s.Add(fromAddr.String(), addrCopy.String(), rs); err != nil { + return err + } + } + + return nil + } + src := raw.(*ResourceState).deepcopy() // Initialize the resource @@ -271,6 +293,8 @@ func detectValueAddLoc(raw interface{}) stateAddLoc { return stateAddModule case *ResourceState: return stateAddResource + case []*ResourceState: + return stateAddResource case *InstanceState: return stateAddInstance default: diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 4270ccc03211..bb1e619c1b29 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -371,6 +371,51 @@ func TestStateAdd(t *testing.T) { }, }, + "ResourceState with count unspecified => Resource Addr (new)": { + false, + "aws_instance.bar", + "aws_instance.foo", + []*ResourceState{ + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + + &State{}, + &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root"}, + Resources: map[string]*ResourceState{ + "aws_instance.foo.0": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + + "aws_instance.foo.1": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + }, + }, + }, + }, + "ResourceState => Resource Addr (existing)": { true, "aws_instance.bar", From 88649ed01038ff681547cc0aa0b01d56672a98f7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 11:51:31 -0400 Subject: [PATCH 041/100] terraform: StateAdd edge case test for multi-count to single index --- terraform/state_add.go | 8 ++++++++ terraform/state_add_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/terraform/state_add.go b/terraform/state_add.go index f78d293a70ec..57a8925d657b 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -160,6 +160,14 @@ func stateAddFunc_Resource_Resource(s *State, fromAddr, addr *ResourceAddress, r return fmt.Errorf("resource move with no value to: %s", addr) } + // If there is an index, this is an error since we can't assign + // a set of resources to a single index + if addr.Index >= 0 { + return fmt.Errorf( + "multiple resources can't be moved to a single index: "+ + "%s => %s", fromAddr, addr) + } + // Add each with a specific index for i, rs := range list { addrCopy := addr.Copy() diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index bb1e619c1b29..8afc428e064e 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -416,6 +416,30 @@ func TestStateAdd(t *testing.T) { }, }, + "ResourceState with count unspecified => Resource Addr (new with count)": { + true, + "aws_instance.bar", + "aws_instance.foo[0]", + []*ResourceState{ + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "bar", + }, + }, + }, + + &State{}, + nil, + }, + "ResourceState => Resource Addr (existing)": { true, "aws_instance.bar", From 8afbb0ee0ea365035a7c11fb0ee7c1c730c003b3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 11:54:53 -0400 Subject: [PATCH 042/100] terraform: state mv "foo" to "foo.0" with single count --- terraform/state_add.go | 2 +- terraform/state_add_test.go | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/terraform/state_add.go b/terraform/state_add.go index 57a8925d657b..033f20614e2a 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -162,7 +162,7 @@ func stateAddFunc_Resource_Resource(s *State, fromAddr, addr *ResourceAddress, r // If there is an index, this is an error since we can't assign // a set of resources to a single index - if addr.Index >= 0 { + if addr.Index >= 0 && len(list) > 1 { return fmt.Errorf( "multiple resources can't be moved to a single index: "+ "%s => %s", fromAddr, addr) diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 8afc428e064e..99e29ed1160f 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -440,6 +440,66 @@ func TestStateAdd(t *testing.T) { nil, }, + "ResourceState with single count unspecified => Resource Addr (new with count)": { + false, + "aws_instance.bar", + "aws_instance.foo[0]", + []*ResourceState{ + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + + &State{}, + &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root"}, + Resources: map[string]*ResourceState{ + "aws_instance.foo.0": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + }, + }, + }, + + "ResourceState => Resource Addr (new with count)": { + false, + "aws_instance.bar", + "aws_instance.foo[0]", + &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + + &State{}, + &State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: []string{"root"}, + Resources: map[string]*ResourceState{ + "aws_instance.foo.0": &ResourceState{ + Type: "test_instance", + Primary: &InstanceState{ + ID: "foo", + }, + }, + }, + }, + }, + }, + }, + "ResourceState => Resource Addr (existing)": { true, "aws_instance.bar", From 0d1ea84d39340730262c969479967367574d1af4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 12:05:20 -0400 Subject: [PATCH 043/100] command: test for moving resource with count [GH-7797] --- command/state_mv.go | 19 +++++++ command/state_mv_test.go | 110 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/command/state_mv.go b/command/state_mv.go index b16f998281b2..ea6c5a8cc9cc 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -139,6 +139,25 @@ func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) i } return result + + case *terraform.ResourceState: + // If a module state then we should add the full list of modules + result := []*terraform.ResourceState{v} + if len(results) > 1 { + for _, r := range results[1:] { + rs, ok := r.Value.(*terraform.ResourceState) + if !ok { + continue + } + + if rs.Type == v.Type { + result = append(result, rs) + } + } + } + + return result + default: // By default just add the first result return v diff --git a/command/state_mv_test.go b/command/state_mv_test.go index bec0504aaa7b..4a81e79b2e5a 100644 --- a/command/state_mv_test.go +++ b/command/state_mv_test.go @@ -223,6 +223,83 @@ func TestStateMv_noState(t *testing.T) { } } +func TestStateMv_stateOutNew_count(t *testing.T) { + state := &terraform.State{ + Modules: []*terraform.ModuleState{ + &terraform.ModuleState{ + Path: []string{"root"}, + Resources: map[string]*terraform.ResourceState{ + "test_instance.foo.0": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "foo", + Attributes: map[string]string{ + "foo": "value", + "bar": "value", + }, + }, + }, + + "test_instance.foo.1": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "bar", + Attributes: map[string]string{ + "foo": "value", + "bar": "value", + }, + }, + }, + + "test_instance.bar": &terraform.ResourceState{ + Type: "test_instance", + Primary: &terraform.InstanceState{ + ID: "bar", + Attributes: map[string]string{ + "foo": "value", + "bar": "value", + }, + }, + }, + }, + }, + }, + } + + statePath := testStateFile(t, state) + stateOutPath := statePath + ".out" + + p := testProvider() + ui := new(cli.MockUi) + c := &StateMvCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-state-out", stateOutPath, + "test_instance.foo", + "test_instance.bar", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + // Test it is correct + testStateOutput(t, stateOutPath, testStateMvCount_stateOut) + testStateOutput(t, statePath, testStateMvCount_stateOutSrc) + + // Test we have backups + backups := testStateBackups(t, filepath.Dir(statePath)) + if len(backups) != 1 { + t.Fatalf("bad: %#v", backups) + } + testStateOutput(t, backups[0], testStateMvCount_stateOutOriginal) +} + func TestStateMv_stateOutNew_nestedModule(t *testing.T) { state := &terraform.State{ Modules: []*terraform.ModuleState{ @@ -326,6 +403,39 @@ test_instance.baz: foo = value ` +const testStateMvCount_stateOut = ` +test_instance.bar.0: + ID = foo + bar = value + foo = value +test_instance.bar.1: + ID = bar + bar = value + foo = value +` + +const testStateMvCount_stateOutSrc = ` +test_instance.bar: + ID = bar + bar = value + foo = value +` + +const testStateMvCount_stateOutOriginal = ` +test_instance.bar: + ID = bar + bar = value + foo = value +test_instance.foo.0: + ID = foo + bar = value + foo = value +test_instance.foo.1: + ID = bar + bar = value + foo = value +` + const testStateMvNestedModule_stateOut = ` module.bar: From 43cfd3d1c93410a879f10c2ca762fbb134ac0e74 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 12:09:19 -0400 Subject: [PATCH 044/100] command: fix regressions for state mv with count resource --- command/state_mv.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/command/state_mv.go b/command/state_mv.go index ea6c5a8cc9cc..8a3c2c1affc6 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -156,6 +156,11 @@ func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) i } } + // If we only have one item, add it directly + if len(result) == 1 { + return result[0] + } + return result default: From 679b063a30df89692e3bc82426770711ac3c56a6 Mon Sep 17 00:00:00 2001 From: Noah Webb Date: Fri, 19 Aug 2016 13:55:30 -0400 Subject: [PATCH 045/100] provider/google: changed the format of source_image in autoscaler tests --- .../google/resource_compute_autoscaler_test.go | 4 ++-- ...esource_compute_instance_group_manager_test.go | 10 +++++----- .../google/resource_compute_instance_template.go | 15 ++++++++++----- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/builtin/providers/google/resource_compute_autoscaler_test.go b/builtin/providers/google/resource_compute_autoscaler_test.go index 40f9fcac6c12..00a92592f1bc 100644 --- a/builtin/providers/google/resource_compute_autoscaler_test.go +++ b/builtin/providers/google/resource_compute_autoscaler_test.go @@ -139,7 +139,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -196,7 +196,7 @@ resource "google_compute_instance_template" "foobar" { tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } diff --git a/builtin/providers/google/resource_compute_instance_group_manager_test.go b/builtin/providers/google/resource_compute_instance_group_manager_test.go index 87d4ea3d878a..610793bc683b 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager_test.go +++ b/builtin/providers/google/resource_compute_instance_group_manager_test.go @@ -277,7 +277,7 @@ func testAccInstanceGroupManager_basic(template, target, igm1, igm2 string) stri tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -331,7 +331,7 @@ func testAccInstanceGroupManager_update(template, target, igm string) string { tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -380,7 +380,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -411,7 +411,7 @@ func testAccInstanceGroupManager_update2(template1, target, template2, igm strin tags = ["foo", "bar"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } @@ -456,7 +456,7 @@ func testAccInstanceGroupManager_updateLifecycle(tag, igm string) string { tags = ["%s"] disk { - source_image = "debian-8-jessie-v20160803" + source_image = "debian-cloud/debian-7-wheezy-v20160301" auto_delete = true boot = true } diff --git a/builtin/providers/google/resource_compute_instance_template.go b/builtin/providers/google/resource_compute_instance_template.go index 9b448f1a9f51..1b76bc7dba10 100644 --- a/builtin/providers/google/resource_compute_instance_template.go +++ b/builtin/providers/google/resource_compute_instance_template.go @@ -585,13 +585,18 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac return resourceComputeInstanceTemplateRead(d, meta) } -func flattenDisks(disks []*compute.AttachedDisk) []map[string]interface{} { +func flattenDisks(disks []*compute.AttachedDisk, d *schema.ResourceData) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(disks)) - for _, disk := range disks { + for i, disk := range disks { diskMap := make(map[string]interface{}) if disk.InitializeParams != nil { - sourceImageUrl := strings.Split(disk.InitializeParams.SourceImage, "/") - diskMap["source_image"] = sourceImageUrl[len(sourceImageUrl)-1] + var source_img = fmt.Sprintf("disk.%d.source_image", i) + if d.Get(source_img) == nil || d.Get(source_img) == "" { + sourceImageUrl := strings.Split(disk.InitializeParams.SourceImage, "/") + diskMap["source_image"] = sourceImageUrl[len(sourceImageUrl)-1] + } else { + diskMap["source_image"] = d.Get(source_img) + } diskMap["disk_type"] = disk.InitializeParams.DiskType diskMap["disk_name"] = disk.InitializeParams.DiskName diskMap["disk_size_gb"] = disk.InitializeParams.DiskSizeGb @@ -701,7 +706,7 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{ d.Set("self_link", instanceTemplate.SelfLink) d.Set("name", instanceTemplate.Name) if instanceTemplate.Properties.Disks != nil { - d.Set("disk", flattenDisks(instanceTemplate.Properties.Disks)) + d.Set("disk", flattenDisks(instanceTemplate.Properties.Disks, d)) } d.Set("description", instanceTemplate.Description) d.Set("machine_type", instanceTemplate.Properties.MachineType) From 771155cea519c3df06627ea05f99d057b84cbb7b Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 19 Aug 2016 14:07:53 -0500 Subject: [PATCH 046/100] provider/aws: Add support for TargetGroups to AutoScaling Groups (#8327) * start of ALB support. Waiting for ALB top level to move forward * initial test * cleanup * small docs * beef up test --- .../aws/resource_aws_autoscaling_group.go | 50 +++ .../resource_aws_autoscaling_group_test.go | 339 ++++++++++++++++++ .../aws/r/autoscaling_group.html.markdown | 6 +- 3 files changed, 394 insertions(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index 98c77a81cc83..2dc460dee229 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -169,6 +169,13 @@ func resourceAwsAutoscalingGroup() *schema.Resource { Default: false, }, + "target_group_arns": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "tag": autoscalingTagsSchema(), }, } @@ -236,6 +243,10 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) autoScalingGroupOpts.TerminationPolicies = expandStringList(v.([]interface{})) } + if v, ok := d.GetOk("target_group_arns"); ok && len(v.(*schema.Set).List()) > 0 { + autoScalingGroupOpts.TargetGroupARNs = expandStringList(v.(*schema.Set).List()) + } + log.Printf("[DEBUG] AutoScaling Group create configuration: %#v", autoScalingGroupOpts) _, err := conn.CreateAutoScalingGroup(&autoScalingGroupOpts) if err != nil { @@ -279,6 +290,9 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e d.Set("health_check_type", g.HealthCheckType) d.Set("launch_configuration", g.LaunchConfigurationName) d.Set("load_balancers", flattenStringList(g.LoadBalancerNames)) + if err := d.Set("target_group_arns", flattenStringList(g.TargetGroupARNs)); err != nil { + log.Printf("[ERR] Error setting target groups: %s", err) + } d.Set("min_size", g.MinSize) d.Set("max_size", g.MaxSize) d.Set("placement_group", g.PlacementGroup) @@ -422,6 +436,42 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) } } + if d.HasChange("target_group_arns") { + + o, n := d.GetChange("target_group_arns") + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } + + os := o.(*schema.Set) + ns := n.(*schema.Set) + remove := expandStringList(os.Difference(ns).List()) + add := expandStringList(ns.Difference(os).List()) + + if len(remove) > 0 { + _, err := conn.DetachLoadBalancerTargetGroups(&autoscaling.DetachLoadBalancerTargetGroupsInput{ + AutoScalingGroupName: aws.String(d.Id()), + TargetGroupARNs: remove, + }) + if err != nil { + return fmt.Errorf("[WARN] Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err) + } + } + + if len(add) > 0 { + _, err := conn.AttachLoadBalancerTargetGroups(&autoscaling.AttachLoadBalancerTargetGroupsInput{ + AutoScalingGroupName: aws.String(d.Id()), + TargetGroupARNs: add, + }) + if err != nil { + return fmt.Errorf("[WARN] Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err) + } + } + } + if shouldWaitForCapacity { waitForASGCapacity(d, meta, capacitySatifiedUpdate) } diff --git a/builtin/providers/aws/resource_aws_autoscaling_group_test.go b/builtin/providers/aws/resource_aws_autoscaling_group_test.go index bd737872c946..716042dba504 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group_test.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group_test.go @@ -4,12 +4,14 @@ import ( "fmt" "reflect" "regexp" + "sort" "strings" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/aws/aws-sdk-go/service/elbv2" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -318,6 +320,83 @@ func TestAccAWSAutoScalingGroup_withMetrics(t *testing.T) { }) } +func TestAccAWSAutoScalingGroup_ALB_TargetGroups(t *testing.T) { + var group autoscaling.Group + var tg elbv2.TargetGroup + var tg2 elbv2.TargetGroup + + testCheck := func(targets []*elbv2.TargetGroup) resource.TestCheckFunc { + return func(*terraform.State) error { + var ts []string + var gs []string + for _, t := range targets { + ts = append(ts, *t.TargetGroupArn) + } + + for _, s := range group.TargetGroupARNs { + gs = append(gs, *s) + } + + sort.Strings(ts) + sort.Strings(gs) + + if !reflect.DeepEqual(ts, gs) { + return fmt.Errorf("Error: target group match not found!\nASG Target groups: %#v\nTarget Group: %#v", ts, gs) + } + return nil + } + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "0"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post_duo, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test_more", &tg2), + testCheck([]*elbv2.TargetGroup{&tg, &tg2}), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "2"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + testCheck([]*elbv2.TargetGroup{&tg}), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "1"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "0"), + ), + }, + }, + }) +} + func testAccCheckAWSAutoScalingGroupDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).autoscalingconn @@ -881,3 +960,263 @@ resource "aws_autoscaling_group" "bar" { metrics_granularity = "1Minute" } ` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + target_group_arns = ["${aws_alb_target_group.test.arn}"] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post_duo = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_alb_target_group" "test_more" { + name = "tf-example-alb-tg-more" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + target_group_arns = [ + "${aws_alb_target_group.test.arn}", + "${aws_alb_target_group.test_more.arn}", + ] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` diff --git a/website/source/docs/providers/aws/r/autoscaling_group.html.markdown b/website/source/docs/providers/aws/r/autoscaling_group.html.markdown index f3caab2d9fc0..d11062cb59e8 100644 --- a/website/source/docs/providers/aws/r/autoscaling_group.html.markdown +++ b/website/source/docs/providers/aws/r/autoscaling_group.html.markdown @@ -67,6 +67,8 @@ The following arguments are supported: * `load_balancers` (Optional) A list of load balancer names to add to the autoscaling group names. * `vpc_zone_identifier` (Optional) A list of subnet IDs to launch resources in. +* `target_group_arns` (Optional) A list of `aws_target_group` ARNs, for use with +Application Load Balancing * `termination_policies` (Optional) A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default`. * `tag` (Optional) A list of tag blocks. Tags documented below. * `placement_group` (Optional) The name of the placement group into which you'll launch your instances, if any. @@ -114,6 +116,8 @@ The following attributes are exported: * `vpc_zone_identifier` (Optional) - The VPC zone identifier * `load_balancers` (Optional) The load balancer names associated with the autoscaling group. +* `target_group_arns` (Optional) list of Target Group ARNs that apply to this +AutoScaling Group ~> **NOTE:** When using `ELB` as the health_check_type, `health_check_grace_period` is required. @@ -186,4 +190,4 @@ AutoScaling Groups can be imported using the `name`, e.g. ``` $ terraform import aws_autoscaling_group.web web-asg -``` \ No newline at end of file +``` From d57da22042f40cb220139fd6ec89b3dc81138875 Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 19 Aug 2016 14:09:03 -0500 Subject: [PATCH 047/100] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3883cf550727..f3bb5388cdab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ FEATURES: IMPROVEMENTS * provider/archive support folders in output_path [GH-8278] * provider/aws: Introduce `aws_elasticsearch_domain` `elasticsearch_version` field (to specify ES version) [GH-7860] + * provider/aws: Add support for TargetGroups (`aws_alb_target_groups`) to `aws_autoscaling_group` [8327] * provider/aws: CloudWatch Metrics are now supported for `aws_route53_health_check` resources [GH-8319] * provider/aws: Query all pages of group membership [GH-6726] * provider/aws: Query all pages of IAM Policy attachments [GH-7779] From 55ba6ebd3d0e7800bc3755690ab60f6e4ca8bf94 Mon Sep 17 00:00:00 2001 From: clint Date: Fri, 19 Aug 2016 19:58:17 +0000 Subject: [PATCH 048/100] v0.7.1 --- CHANGELOG.md | 194 +++++++++++++++++++++---------------------- terraform/version.go | 2 +- website/config.rb | 2 +- 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3bb5388cdab..76842c47f7b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,108 +1,108 @@ -## 0.7.1 (Unreleased) +## 0.7.1 (August 19, 2016) FEATURES: - * **New Command:** `terraform state rm` [GH-8200] - * **New Provider:** `archive` [GH-7322] - * **New Resource:** `aws_alb` [GH-8254] - * **New Resource:** `aws_alb_listener` [GH-8269] - * **New Resource:** `aws_alb_target_group` [GH-8254] - * **New Resource:** `aws_alb_target_group_attachment` [GH-8254] - * **New Resource:** `aws_alb_target_group_rule` [GH-8321] - * **New Resource:** `aws_vpn_gateway_attachment` [GH-7870] - * **New Resource:** `aws_load_balancer_policy` [GH-7458] - * **New Resource:** `aws_load_balancer_backend_server_policy` [GH-7458] - * **New Resource:** `aws_load_balancer_listener_policy` [GH-7458] - * **New Resource:** `aws_lb_ssl_negotiation_policy` [GH-8084] - * **New Resource:** `aws_elasticache_replication_groups` [GH-8275] - * **New Resource:** `azurerm_virtual_network_peering` [GH-8168] - * **New Resource:** `azurerm_servicebus_namespace` [GH-8195] - * **New Resource:** `google_compute_image` [GH-7960] - * **New Resource:** `packet_volume` [GH-8142] - * **New Resource:** `consul_prepared_query` [GH-7474] - * **New Data Source:** `aws_ip_ranges` [GH-7984] - * **New Data Source:** `fastly_ip_ranges` [GH-7984] - * **New Data Source:** `aws_caller_identity` [GH-8206] - * **New Data Source:** `aws_elb_service_account` [GH-8221] - * **New Data Source:** `aws_redshift_service_account` [GH-8224] + * **New Command:** `terraform state rm` ([#8200](https://github.com/hashicorp/terraform/issues/8200)) + * **New Provider:** `archive` ([#7322](https://github.com/hashicorp/terraform/issues/7322)) + * **New Resource:** `aws_alb` ([#8254](https://github.com/hashicorp/terraform/issues/8254)) + * **New Resource:** `aws_alb_listener` ([#8269](https://github.com/hashicorp/terraform/issues/8269)) + * **New Resource:** `aws_alb_target_group` ([#8254](https://github.com/hashicorp/terraform/issues/8254)) + * **New Resource:** `aws_alb_target_group_attachment` ([#8254](https://github.com/hashicorp/terraform/issues/8254)) + * **New Resource:** `aws_alb_target_group_rule` ([#8321](https://github.com/hashicorp/terraform/issues/8321)) + * **New Resource:** `aws_vpn_gateway_attachment` ([#7870](https://github.com/hashicorp/terraform/issues/7870)) + * **New Resource:** `aws_load_balancer_policy` ([#7458](https://github.com/hashicorp/terraform/issues/7458)) + * **New Resource:** `aws_load_balancer_backend_server_policy` ([#7458](https://github.com/hashicorp/terraform/issues/7458)) + * **New Resource:** `aws_load_balancer_listener_policy` ([#7458](https://github.com/hashicorp/terraform/issues/7458)) + * **New Resource:** `aws_lb_ssl_negotiation_policy` ([#8084](https://github.com/hashicorp/terraform/issues/8084)) + * **New Resource:** `aws_elasticache_replication_groups` ([#8275](https://github.com/hashicorp/terraform/issues/8275)) + * **New Resource:** `azurerm_virtual_network_peering` ([#8168](https://github.com/hashicorp/terraform/issues/8168)) + * **New Resource:** `azurerm_servicebus_namespace` ([#8195](https://github.com/hashicorp/terraform/issues/8195)) + * **New Resource:** `google_compute_image` ([#7960](https://github.com/hashicorp/terraform/issues/7960)) + * **New Resource:** `packet_volume` ([#8142](https://github.com/hashicorp/terraform/issues/8142)) + * **New Resource:** `consul_prepared_query` ([#7474](https://github.com/hashicorp/terraform/issues/7474)) + * **New Data Source:** `aws_ip_ranges` ([#7984](https://github.com/hashicorp/terraform/issues/7984)) + * **New Data Source:** `fastly_ip_ranges` ([#7984](https://github.com/hashicorp/terraform/issues/7984)) + * **New Data Source:** `aws_caller_identity` ([#8206](https://github.com/hashicorp/terraform/issues/8206)) + * **New Data Source:** `aws_elb_service_account` ([#8221](https://github.com/hashicorp/terraform/issues/8221)) + * **New Data Source:** `aws_redshift_service_account` ([#8224](https://github.com/hashicorp/terraform/issues/8224)) IMPROVEMENTS - * provider/archive support folders in output_path [GH-8278] - * provider/aws: Introduce `aws_elasticsearch_domain` `elasticsearch_version` field (to specify ES version) [GH-7860] + * provider/archive support folders in output_path ([#8278](https://github.com/hashicorp/terraform/issues/8278)) + * provider/aws: Introduce `aws_elasticsearch_domain` `elasticsearch_version` field (to specify ES version) ([#7860](https://github.com/hashicorp/terraform/issues/7860)) * provider/aws: Add support for TargetGroups (`aws_alb_target_groups`) to `aws_autoscaling_group` [8327] - * provider/aws: CloudWatch Metrics are now supported for `aws_route53_health_check` resources [GH-8319] - * provider/aws: Query all pages of group membership [GH-6726] - * provider/aws: Query all pages of IAM Policy attachments [GH-7779] - * provider/aws: Change the way ARNs are built [GH-7151] - * provider/aws: Add support for Elasticsearch destination to firehose delivery streams [GH-7839] - * provider/aws: Retry AttachInternetGateway and increase timeout on `aws_internet_gateway` [GH-7891] - * provider/aws: Add support for Enhanced monitoring to `aws_rds_cluster_instance` [GH-8038] - * provider/aws: Add ability to set Requests Payer in `aws_s3_bucket` [GH-8065] - * provider/aws: Add ability to set canned ACL in `aws_s3_bucket_object` [GH-8091] - * provider/aws: Allow skipping credentials validation, requesting Account ID and/or metadata API check [GH-7874] - * provider/aws: API gateway request/response parameters can now be specified as map, original `*_in_json` parameters deprecated [GH-7794] - * provider/aws: Add support for `promotion_tier` to `aws_rds_cluster_instance` [GH-8087] - * provider/aws: Allow specifying custom S3 endpoint and enforcing S3 path style URLs via new provider options [GH-7871] - * provider/aws: Add ability to set Storage Class in `aws_s3_bucket_object` [GH-8174] - * provider/aws: Treat `aws_lambda_function` w/ empty `subnet_ids` & `security_groups_ids` in `vpc_config` as VPC-disabled function [GH-6191] - * provider/aws: Allow `source_ids` in `aws_db_event_subscription` to be Updatable [GH-7892] - * provider/aws: Make `aws_efs_mount_target` creation fail for 2+ targets per AZ [GH-8205] - * provider/aws: Add `force_destroy` option to `aws_route53_zone` [GH-8239] - * provider/aws: Support import of `aws_s3_bucket` [GH-8262] - * provider/aws: Increase timeout for retrying creation of IAM role [GH-7733] - * provider/aws: Add ability to set peering options in aws_vpc_peering_connection. [GH-8310] - * provider/azure: add custom_data argument for azure_instance resource [GH-8158] - * provider/azurerm: Adds support for uploading blobs to azure storage from local source [GH-7994] - * provider/azurerm: Storage blob contents can be copied from an existing blob [GH-8126] - * provider/datadog: Allow `tags` to be configured for monitor resources. [GH-8284] - * provider/google: allows atomic Cloud DNS record changes [GH-6575] - * provider/google: Move URLMap hosts to TypeSet from TypeList [GH-7472] - * provider/google: Support static private IP addresses in `resource_compute_instance` [GH-6310] - * provider/google: Add support for using a GCP Image Family [GH-8083] - * provider/openstack: Support updating the External Gateway assigned to a Neutron router [GH-8070] - * provider/openstack: Support for `value_specs` param on `openstack_networking_network_v2` [GH-8155] - * provider/openstack: Add `value_specs` param on `openstack_networking_subnet_v2` [GH-8181] - * provider/vsphere: Improved SCSI controller handling in `vsphere_virtual_machine` [GH-7908] - * provider/vsphere: Adding disk type of `Thick Lazy` to `vsphere_virtual_disk` and `vsphere_virtual_machine` [GH-7916] - * provider/vsphere: Standardizing datastore references to use builtin Path func [GH-8075] - * provider/consul: add tls config support to consul provider [GH-7015] - * remote/consul: Support setting datacenter when using consul remote state [GH-8102] - * provider/google: Support import of `google_compute_instance_template` [GH-8147], `google_compute_firewall` [GH-8236], `google_compute_target_pool` [GH-8133], `google_compute_fowarding_rule` [GH-8122], `google_compute_http_health_check` [GH-8121], `google_compute_autoscaler` [GH-8115] + * provider/aws: CloudWatch Metrics are now supported for `aws_route53_health_check` resources ([#8319](https://github.com/hashicorp/terraform/issues/8319)) + * provider/aws: Query all pages of group membership ([#6726](https://github.com/hashicorp/terraform/issues/6726)) + * provider/aws: Query all pages of IAM Policy attachments ([#7779](https://github.com/hashicorp/terraform/issues/7779)) + * provider/aws: Change the way ARNs are built ([#7151](https://github.com/hashicorp/terraform/issues/7151)) + * provider/aws: Add support for Elasticsearch destination to firehose delivery streams ([#7839](https://github.com/hashicorp/terraform/issues/7839)) + * provider/aws: Retry AttachInternetGateway and increase timeout on `aws_internet_gateway` ([#7891](https://github.com/hashicorp/terraform/issues/7891)) + * provider/aws: Add support for Enhanced monitoring to `aws_rds_cluster_instance` ([#8038](https://github.com/hashicorp/terraform/issues/8038)) + * provider/aws: Add ability to set Requests Payer in `aws_s3_bucket` ([#8065](https://github.com/hashicorp/terraform/issues/8065)) + * provider/aws: Add ability to set canned ACL in `aws_s3_bucket_object` ([#8091](https://github.com/hashicorp/terraform/issues/8091)) + * provider/aws: Allow skipping credentials validation, requesting Account ID and/or metadata API check ([#7874](https://github.com/hashicorp/terraform/issues/7874)) + * provider/aws: API gateway request/response parameters can now be specified as map, original `*_in_json` parameters deprecated ([#7794](https://github.com/hashicorp/terraform/issues/7794)) + * provider/aws: Add support for `promotion_tier` to `aws_rds_cluster_instance` ([#8087](https://github.com/hashicorp/terraform/issues/8087)) + * provider/aws: Allow specifying custom S3 endpoint and enforcing S3 path style URLs via new provider options ([#7871](https://github.com/hashicorp/terraform/issues/7871)) + * provider/aws: Add ability to set Storage Class in `aws_s3_bucket_object` ([#8174](https://github.com/hashicorp/terraform/issues/8174)) + * provider/aws: Treat `aws_lambda_function` w/ empty `subnet_ids` & `security_groups_ids` in `vpc_config` as VPC-disabled function ([#6191](https://github.com/hashicorp/terraform/issues/6191)) + * provider/aws: Allow `source_ids` in `aws_db_event_subscription` to be Updatable ([#7892](https://github.com/hashicorp/terraform/issues/7892)) + * provider/aws: Make `aws_efs_mount_target` creation fail for 2+ targets per AZ ([#8205](https://github.com/hashicorp/terraform/issues/8205)) + * provider/aws: Add `force_destroy` option to `aws_route53_zone` ([#8239](https://github.com/hashicorp/terraform/issues/8239)) + * provider/aws: Support import of `aws_s3_bucket` ([#8262](https://github.com/hashicorp/terraform/issues/8262)) + * provider/aws: Increase timeout for retrying creation of IAM role ([#7733](https://github.com/hashicorp/terraform/issues/7733)) + * provider/aws: Add ability to set peering options in aws_vpc_peering_connection. ([#8310](https://github.com/hashicorp/terraform/issues/8310)) + * provider/azure: add custom_data argument for azure_instance resource ([#8158](https://github.com/hashicorp/terraform/issues/8158)) + * provider/azurerm: Adds support for uploading blobs to azure storage from local source ([#7994](https://github.com/hashicorp/terraform/issues/7994)) + * provider/azurerm: Storage blob contents can be copied from an existing blob ([#8126](https://github.com/hashicorp/terraform/issues/8126)) + * provider/datadog: Allow `tags` to be configured for monitor resources. ([#8284](https://github.com/hashicorp/terraform/issues/8284)) + * provider/google: allows atomic Cloud DNS record changes ([#6575](https://github.com/hashicorp/terraform/issues/6575)) + * provider/google: Move URLMap hosts to TypeSet from TypeList ([#7472](https://github.com/hashicorp/terraform/issues/7472)) + * provider/google: Support static private IP addresses in `resource_compute_instance` ([#6310](https://github.com/hashicorp/terraform/issues/6310)) + * provider/google: Add support for using a GCP Image Family ([#8083](https://github.com/hashicorp/terraform/issues/8083)) + * provider/openstack: Support updating the External Gateway assigned to a Neutron router ([#8070](https://github.com/hashicorp/terraform/issues/8070)) + * provider/openstack: Support for `value_specs` param on `openstack_networking_network_v2` ([#8155](https://github.com/hashicorp/terraform/issues/8155)) + * provider/openstack: Add `value_specs` param on `openstack_networking_subnet_v2` ([#8181](https://github.com/hashicorp/terraform/issues/8181)) + * provider/vsphere: Improved SCSI controller handling in `vsphere_virtual_machine` ([#7908](https://github.com/hashicorp/terraform/issues/7908)) + * provider/vsphere: Adding disk type of `Thick Lazy` to `vsphere_virtual_disk` and `vsphere_virtual_machine` ([#7916](https://github.com/hashicorp/terraform/issues/7916)) + * provider/vsphere: Standardizing datastore references to use builtin Path func ([#8075](https://github.com/hashicorp/terraform/issues/8075)) + * provider/consul: add tls config support to consul provider ([#7015](https://github.com/hashicorp/terraform/issues/7015)) + * remote/consul: Support setting datacenter when using consul remote state ([#8102](https://github.com/hashicorp/terraform/issues/8102)) + * provider/google: Support import of `google_compute_instance_template` ([#8147](https://github.com/hashicorp/terraform/issues/8147)), `google_compute_firewall` ([#8236](https://github.com/hashicorp/terraform/issues/8236)), `google_compute_target_pool` ([#8133](https://github.com/hashicorp/terraform/issues/8133)), `google_compute_fowarding_rule` ([#8122](https://github.com/hashicorp/terraform/issues/8122)), `google_compute_http_health_check` ([#8121](https://github.com/hashicorp/terraform/issues/8121)), `google_compute_autoscaler` ([#8115](https://github.com/hashicorp/terraform/issues/8115)) BUG FIXES: - * core: Fix issue preventing `taint` from working with resources that had no other attributes in their diff [GH-8167] - * core: CLI will only run exact match commands [GH-7983] - * core: Fix panic when resources ends up null in state file [GH-8120] - * core: Fix panic when validating a count with a unprefixed variable [GH-8243] - * core: Divide by zero in interpolations no longer panics [GH-7701] - * core: Fix panic on some invalid interpolation syntax [GH-5672] - * provider/aws: guard against missing image_digest in `aws_ecs_task_definition` [GH-7966] - * provider/aws: `aws_cloudformation_stack` now respects `timeout_in_minutes` field when waiting for CF API to finish an update operation [GH-7997] - * provider/aws: Prevent errors when `aws_s3_bucket` `acceleration_status` is not available in a given region [GH-7999] - * provider/aws: Add state filter to `aws_availability_zone`s data source [GH-7965] - * provider/aws: Handle lack of snapshot ID for a volume in `ami_copy` [GH-7995] - * provider/aws: Retry association of IAM Role & instance profile [GH-7938] - * provider/aws: Fix `aws_s3_bucket` resource `redirect_all_requests_to` action [GH-7883] - * provider/aws: Fix issue updating ElasticBeanstalk Environment Settings [GH-7777] - * provider/aws: `aws_rds_cluster` creation timeout bumped to 40 minutes [GH-8052] - * provider/aws: Update ElasticTranscoder to allow empty notifications, removing notifications, etc [GH-8207] - * provider/aws: Fix line ending errors/diffs with IAM Server Certs [GH-8074] - * provider/aws: Fixing IAM data source policy generation to prevent spurious diffs [GH-6956] - * provider/aws: Correct how CORS rules are handled in `aws_s3_bucket` [GH-8096] - * provider/aws: allow numeric characters in RedshiftClusterDbName [GH-8178] - * provider/aws: `aws_security_group` now creates tags as early as possible in the process [GH-7849] - * provider/aws: Defensively code around `db_security_group` ingress rules [GH-7893] - * provider/aws: `aws_spot_fleet_request` throws panic on missing subnet_id or availability_zone [GH-8217] - * provider/aws: Terraform fails during Redshift delete if FinalSnapshot is being taken. [GH-8270] - * provider/azurerm: `azurerm_storage_account` will interrupt for Ctrl-C [GH-8215] + * core: Fix issue preventing `taint` from working with resources that had no other attributes in their diff ([#8167](https://github.com/hashicorp/terraform/issues/8167)) + * core: CLI will only run exact match commands ([#7983](https://github.com/hashicorp/terraform/issues/7983)) + * core: Fix panic when resources ends up null in state file ([#8120](https://github.com/hashicorp/terraform/issues/8120)) + * core: Fix panic when validating a count with a unprefixed variable ([#8243](https://github.com/hashicorp/terraform/issues/8243)) + * core: Divide by zero in interpolations no longer panics ([#7701](https://github.com/hashicorp/terraform/issues/7701)) + * core: Fix panic on some invalid interpolation syntax ([#5672](https://github.com/hashicorp/terraform/issues/5672)) + * provider/aws: guard against missing image_digest in `aws_ecs_task_definition` ([#7966](https://github.com/hashicorp/terraform/issues/7966)) + * provider/aws: `aws_cloudformation_stack` now respects `timeout_in_minutes` field when waiting for CF API to finish an update operation ([#7997](https://github.com/hashicorp/terraform/issues/7997)) + * provider/aws: Prevent errors when `aws_s3_bucket` `acceleration_status` is not available in a given region ([#7999](https://github.com/hashicorp/terraform/issues/7999)) + * provider/aws: Add state filter to `aws_availability_zone`s data source ([#7965](https://github.com/hashicorp/terraform/issues/7965)) + * provider/aws: Handle lack of snapshot ID for a volume in `ami_copy` ([#7995](https://github.com/hashicorp/terraform/issues/7995)) + * provider/aws: Retry association of IAM Role & instance profile ([#7938](https://github.com/hashicorp/terraform/issues/7938)) + * provider/aws: Fix `aws_s3_bucket` resource `redirect_all_requests_to` action ([#7883](https://github.com/hashicorp/terraform/issues/7883)) + * provider/aws: Fix issue updating ElasticBeanstalk Environment Settings ([#7777](https://github.com/hashicorp/terraform/issues/7777)) + * provider/aws: `aws_rds_cluster` creation timeout bumped to 40 minutes ([#8052](https://github.com/hashicorp/terraform/issues/8052)) + * provider/aws: Update ElasticTranscoder to allow empty notifications, removing notifications, etc ([#8207](https://github.com/hashicorp/terraform/issues/8207)) + * provider/aws: Fix line ending errors/diffs with IAM Server Certs ([#8074](https://github.com/hashicorp/terraform/issues/8074)) + * provider/aws: Fixing IAM data source policy generation to prevent spurious diffs ([#6956](https://github.com/hashicorp/terraform/issues/6956)) + * provider/aws: Correct how CORS rules are handled in `aws_s3_bucket` ([#8096](https://github.com/hashicorp/terraform/issues/8096)) + * provider/aws: allow numeric characters in RedshiftClusterDbName ([#8178](https://github.com/hashicorp/terraform/issues/8178)) + * provider/aws: `aws_security_group` now creates tags as early as possible in the process ([#7849](https://github.com/hashicorp/terraform/issues/7849)) + * provider/aws: Defensively code around `db_security_group` ingress rules ([#7893](https://github.com/hashicorp/terraform/issues/7893)) + * provider/aws: `aws_spot_fleet_request` throws panic on missing subnet_id or availability_zone ([#8217](https://github.com/hashicorp/terraform/issues/8217)) + * provider/aws: Terraform fails during Redshift delete if FinalSnapshot is being taken. ([#8270](https://github.com/hashicorp/terraform/issues/8270)) + * provider/azurerm: `azurerm_storage_account` will interrupt for Ctrl-C ([#8215](https://github.com/hashicorp/terraform/issues/8215)) * provider/azurerm: Public IP - Setting idle timeout value caused panic. #8283 - * provider/digitalocean: trim whitespace from ssh key [GH-8173] - * provider/digitalocean: Enforce Lowercase on IPV6 Addresses [GH-7652] - * provider/google: Use resource specific project when making queries/changes [GH-7029] - * provider/google: Fix read for the backend service resource [GH-7476] - * provider/mysql: `mysql_user` works with MySQL versions before 5.7.6 [GH-8251] - * provider/openstack: Fix typo in OpenStack LBaaSv2 pool resource [GH-8179] - * provider/vSphere: Fix for IPv6 only environment creation [GH-7643] - * provider/google: Correct update process for authorized networks in `google_sql_database_instance` [GH-8290] + * provider/digitalocean: trim whitespace from ssh key ([#8173](https://github.com/hashicorp/terraform/issues/8173)) + * provider/digitalocean: Enforce Lowercase on IPV6 Addresses ([#7652](https://github.com/hashicorp/terraform/issues/7652)) + * provider/google: Use resource specific project when making queries/changes ([#7029](https://github.com/hashicorp/terraform/issues/7029)) + * provider/google: Fix read for the backend service resource ([#7476](https://github.com/hashicorp/terraform/issues/7476)) + * provider/mysql: `mysql_user` works with MySQL versions before 5.7.6 ([#8251](https://github.com/hashicorp/terraform/issues/8251)) + * provider/openstack: Fix typo in OpenStack LBaaSv2 pool resource ([#8179](https://github.com/hashicorp/terraform/issues/8179)) + * provider/vSphere: Fix for IPv6 only environment creation ([#7643](https://github.com/hashicorp/terraform/issues/7643)) + * provider/google: Correct update process for authorized networks in `google_sql_database_instance` ([#8290](https://github.com/hashicorp/terraform/issues/8290)) ## 0.7.0 (August 2, 2016) diff --git a/terraform/version.go b/terraform/version.go index ae5f1f7cbaba..56e6456f0b5b 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -12,7 +12,7 @@ const Version = "0.7.1" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" // SemVersion is an instance of version.Version. This has the secondary // benefit of verifying during tests and init time that our version is a diff --git a/website/config.rb b/website/config.rb index bf97974b0016..618a87800690 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,6 +2,6 @@ activate :hashicorp do |h| h.name = "terraform" - h.version = "0.7.0" + h.version = "0.7.1" h.github_slug = "hashicorp/terraform" end From 146da09d5d33eb628acb6abda4ffc51c6d6e0070 Mon Sep 17 00:00:00 2001 From: clint Date: Fri, 19 Aug 2016 20:28:17 +0000 Subject: [PATCH 049/100] release: clean up after v0.7.1 --- CHANGELOG.md | 2 ++ terraform/version.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76842c47f7b1..4a125e5b3892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.7.2 (Unreleased) + ## 0.7.1 (August 19, 2016) FEATURES: diff --git a/terraform/version.go b/terraform/version.go index 56e6456f0b5b..1eff034d5e39 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -7,12 +7,12 @@ import ( ) // The main version number that is being run at the moment. -const Version = "0.7.1" +const Version = "0.7.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" // SemVersion is an instance of version.Version. This has the secondary // benefit of verifying during tests and init time that our version is a From c22ab252ddf242ea96f26635889eebf97d46fc19 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 19:14:33 -0400 Subject: [PATCH 050/100] terraform: import specific index works [GH-7691] --- terraform/context_import_test.go | 40 +++++++++++++++++++++++++++++ terraform/transform_import_state.go | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/terraform/context_import_test.go b/terraform/context_import_test.go index 1f9489c18366..f344fac95d3b 100644 --- a/terraform/context_import_test.go +++ b/terraform/context_import_test.go @@ -40,6 +40,40 @@ func TestContextImport_basic(t *testing.T) { } } +func TestContextImport_countIndex(t *testing.T) { + p := testProvider("aws") + ctx := testContext2(t, &ContextOpts{ + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + }) + + p.ImportStateReturn = []*InstanceState{ + &InstanceState{ + ID: "foo", + Ephemeral: EphemeralState{Type: "aws_instance"}, + }, + } + + state, err := ctx.Import(&ImportOpts{ + Targets: []*ImportTarget{ + &ImportTarget{ + Addr: "aws_instance.foo[0]", + ID: "bar", + }, + }, + }) + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(state.String()) + expected := strings.TrimSpace(testImportCountIndexStr) + if actual != expected { + t.Fatalf("bad: \n%s", actual) + } +} + func TestContextImport_collision(t *testing.T) { p := testProvider("aws") ctx := testContext2(t, &ContextOpts{ @@ -508,6 +542,12 @@ aws_instance.foo: provider = aws ` +const testImportCountIndexStr = ` +aws_instance.foo.0: + ID = foo + provider = aws +` + const testImportCollisionStr = ` aws_instance.foo: ID = bar diff --git a/terraform/transform_import_state.go b/terraform/transform_import_state.go index 2324aea0fa68..389c0464e3f7 100644 --- a/terraform/transform_import_state.go +++ b/terraform/transform_import_state.go @@ -204,7 +204,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode { key := &ResourceStateKey{ Name: n.Target.Name, Type: info.Type, - Index: -1, + Index: n.Target.Index, } // The eval sequence From 0b165164c408642b638eb1d40b7fe27094627991 Mon Sep 17 00:00:00 2001 From: kyhavlov Date: Fri, 19 Aug 2016 20:35:00 -0400 Subject: [PATCH 051/100] docs: Fix exported attribute name in docker_registry_image --- .../source/docs/providers/docker/d/registry_image.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/providers/docker/d/registry_image.html.markdown b/website/source/docs/providers/docker/d/registry_image.html.markdown index 740ac76e4a07..6f8213677200 100644 --- a/website/source/docs/providers/docker/d/registry_image.html.markdown +++ b/website/source/docs/providers/docker/d/registry_image.html.markdown @@ -37,4 +37,4 @@ The following arguments are supported: The following attributes are exported in addition to the above configuration: -* `id` (string) - The ID of the image, as stored on the registry. +* `sha256_digest` (string) - The content digest of the image, as stored on the registry. From d3792e4aefcb00fb4f5e39e4055b849119ae6842 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 23:56:27 -0400 Subject: [PATCH 052/100] command: correct outdated comment --- command/state_mv.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/command/state_mv.go b/command/state_mv.go index 8a3c2c1affc6..37ce53bea373 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -141,7 +141,8 @@ func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) i return result case *terraform.ResourceState: - // If a module state then we should add the full list of modules + // If a resource state with more than one result, it has a multi-count + // and we need to add all of them. result := []*terraform.ResourceState{v} if len(results) > 1 { for _, r := range results[1:] { From 52c359bad090cb89bfa89f2d4590f6f7b2032e9d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Aug 2016 23:58:28 -0400 Subject: [PATCH 053/100] update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a125e5b3892..dea431408042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 0.7.2 (Unreleased) +BUG FIXES: + * command/import: can import into specific indexes [GH-8335] + ## 0.7.1 (August 19, 2016) FEATURES: From 469856dbf1eb2e5e287bce23717d0544cd7d57a3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 20 Aug 2016 00:00:59 -0400 Subject: [PATCH 054/100] update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dea431408042..5bc8eada969b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ BUG FIXES: * command/import: can import into specific indexes [GH-8335] + * command/state mv: nested modules can be moved [GH-8304] + * command/state mv: resources with a count > 1 can be moved [GH-8304] ## 0.7.1 (August 19, 2016) From 19ecb40c48bbbc23390636c08c54eef06bab4236 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Sat, 20 Aug 2016 10:14:51 +0100 Subject: [PATCH 055/100] provider/azurerm: Setting the AzureRM SDK to an explicit version (#8303) We tended to use master which isn't the best idea. Also set Go Autorest to the correct version (7.1.0) --- .../autorest/azure/environments.go | 24 +++- .../Azure/go-autorest/autorest/client.go | 9 +- .../Azure/go-autorest/autorest/preparer.go | 60 +++++++++ .../Azure/go-autorest/autorest/utility.go | 17 +++ vendor/vendor.json | 124 +++++++++++++----- 5 files changed, 193 insertions(+), 41 deletions(-) diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go index 57ec71580a73..ebf754eab4fb 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go @@ -3,12 +3,20 @@ package azure import ( "fmt" "net/url" + "strings" ) const ( activeDirectoryAPIVersion = "1.0" ) +var environments = map[string]Environment{ + "AZURECHINACLOUD": ChinaCloud, + "AZUREGERMANCLOUD": GermanCloud, + "AZUREPUBLICCLOUD": PublicCloud, + "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, +} + // Environment represents a set of endpoints for each of Azure's Clouds. type Environment struct { Name string `json:"name"` @@ -52,7 +60,7 @@ var ( ManagementPortalURL: "https://manage.windowsazure.us/", PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", - ResourceManagerEndpoint: "https://management.usgovcloudapi.net", + ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", GalleryEndpoint: "https://gallery.usgovcloudapi.net/", KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", @@ -87,8 +95,8 @@ var ( Name: "AzureGermanCloud", ManagementPortalURL: "http://portal.microsoftazure.de/", PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.cloudapi.de", - ResourceManagerEndpoint: "https://management.microsoftazure.de", + ServiceManagementEndpoint: "https://management.core.cloudapi.de/", + ResourceManagerEndpoint: "https://management.microsoftazure.de/", ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", GalleryEndpoint: "https://gallery.cloudapi.de/", KeyVaultEndpoint: "https://vault.microsoftazure.de/", @@ -101,6 +109,16 @@ var ( } ) +// EnvironmentFromName returns an Environment based on the common name specified +func EnvironmentFromName(name string) (Environment, error) { + name = strings.ToUpper(name) + env, ok := environments[name] + if !ok { + return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) + } + return env, nil +} + // OAuthConfigForTenant returns an OAuthConfig with tenant specific urls func (env Environment) OAuthConfigForTenant(tenantID string) (*OAuthConfig, error) { template := "%s/oauth2/%s?api-version=%s" diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go index 95e9a203d880..b55b3d103534 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ b/vendor/github.com/Azure/go-autorest/autorest/client.go @@ -20,9 +20,6 @@ const ( // DefaultRetryAttempts is number of attempts for retry status codes (5xx). DefaultRetryAttempts = 3 - - // DefaultRetryDuration is a resonable delay for retry. - defaultRetryInterval = 30 * time.Second ) var statusCodesForRetry = []int{ @@ -130,6 +127,9 @@ type Client struct { // RetryAttempts sets the default number of retry attempts for client. RetryAttempts int + // RetryDuration sets the delay duration for retries. + RetryDuration time.Duration + // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent // through the Do method. UserAgent string @@ -144,6 +144,7 @@ func NewClientWithUserAgent(ua string) Client { PollingDelay: DefaultPollingDelay, PollingDuration: DefaultPollingDuration, RetryAttempts: DefaultRetryAttempts, + RetryDuration: 30 * time.Second, UserAgent: ua, } } @@ -163,7 +164,7 @@ func (c Client) Do(r *http.Request) (*http.Response, error) { return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") } resp, err := SendWithSender(c.sender(), r, - DoRetryForStatusCodes(c.RetryAttempts, defaultRetryInterval, statusCodesForRetry...)) + DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...)) Respond(resp, c.ByInspecting()) return resp, err diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go index 0f18c2aced86..5b2c52704a29 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ b/vendor/github.com/Azure/go-autorest/autorest/preparer.go @@ -4,7 +4,9 @@ import ( "bytes" "encoding/json" "fmt" + "io" "io/ioutil" + "mime/multipart" "net/http" "net/url" "strings" @@ -197,6 +199,64 @@ func WithFormData(v url.Values) PrepareDecorator { } } +// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters +// into the http.Request body. +func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + var body bytes.Buffer + writer := multipart.NewWriter(&body) + for key, value := range formDataParameters { + if rc, ok := value.(io.ReadCloser); ok { + var fd io.Writer + if fd, err = writer.CreateFormFile(key, key); err != nil { + return r, err + } + if _, err = io.Copy(fd, rc); err != nil { + return r, err + } + } else { + if err = writer.WriteField(key, ensureValueString(value)); err != nil { + return r, err + } + } + } + if err = writer.Close(); err != nil { + return r, err + } + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) + r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) + r.ContentLength = int64(body.Len()) + return r, err + } + return r, err + }) + } +} + +// WithFile returns a PrepareDecorator that sends file in request body. +func WithFile(f io.ReadCloser) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := ioutil.ReadAll(f) + if err != nil { + return r, err + } + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + r.ContentLength = int64(len(b)) + } + return r, err + }) + } +} + // WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request // and sets the Content-Length header. func WithBool(v bool) PrepareDecorator { diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go index b7f4a723b1c8..78067148b28d 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/url" + "reflect" "sort" "strings" ) @@ -106,6 +107,22 @@ func ensureValueString(value interface{}) string { } } +// MapToValues method converts map[string]interface{} to url.Values. +func MapToValues(m map[string]interface{}) url.Values { + v := url.Values{} + for key, value := range m { + x := reflect.ValueOf(value) + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + for i := 0; i < x.Len(); i++ { + v.Add(key, ensureValueString(x.Index(i))) + } + } else { + v.Add(key, ensureValueString(value)) + } + } + return v +} + // String method converts interface v to string. If interface is a list, it // joins list elements using separator. func String(v interface{}, sep ...string) string { diff --git a/vendor/vendor.json b/vendor/vendor.json index ed1a11febd18..750c1df84965 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -7,194 +7,250 @@ "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/cdn", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "88TAbW2kN6NighEaL9X8IKNp3Go=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/compute", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "AdWY+YN439QSBtAFqG/dIV93J38=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/network", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "EdND5GRzWDkSwl18UVWJJgsnOG4=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/resources/resources", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "iFV4QVdtS6bx3fNhjDAyS/Eiw+Y=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/scheduler", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "jskb+xe0vrZayq7Iu9yyJXo+Kmc=", "path": "github.com/Azure/azure-sdk-for-go/arm/servicebus", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "jh7wjswBwwVeY/P8wtqtqBR58y4=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/arm/storage", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "PLyDrzfgTsbkk7HsuJxbj8QmTC4=", "path": "github.com/Azure/azure-sdk-for-go/arm/trafficmanager", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "Q+0Zz0iylSKMck4JhYc8XR83i8M=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/core/http", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "F2fqk+OPM3drSkK0G6So5ASayyA=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/core/tls", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "SGOuRzxuQpJChBvq6SsNojKvcKw=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "TcQ6KXoBkvUhCYeggJ/bwcz+QaQ=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/affinitygroup", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "HfjyhRfmKBsVgWLTOfWVcxe8Z88=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/hostedservice", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "4otMhU6xZ41HfmiGZFYtV93GdcI=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/location", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "hxivwm3D13cqFGOlOS3q8HD7DN0=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/networksecuritygroup", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "2USoeYg8k1tA1QNLRByEnP/asqs=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/osimage", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "hzwziaU5QlMlFcFPdbEmW18oV3Y=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/sql", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "YoAhDE0X6hSFuPpXbpfqcTC0Zvw=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/storageservice", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "6xEiZL4a9rr5YbnY0RdzuzhEF1Q=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/virtualmachine", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "xcBM3zQtfcE3VHNBACJJGEesCBI=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/virtualmachinedisk", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "0bfdkDZ2JFV7bol6GQFfC0g+lP4=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/virtualmachineimage", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "IhjDqm84VDVSIoHyiGvUzuljG3s=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/virtualnetwork", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "+ykSkHo40/f6VK6/zXDqzF8Lh14=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/management/vmutils", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { "checksumSHA1": "w1X4Sxcdx4WhCqVZdPWoUuMPn9U=", "comment": "v2.1.1-beta-8-gca4d906", "path": "github.com/Azure/azure-sdk-for-go/storage", "revision": "bfc5b4af08f3d3745d908af36b7ed5b9060f0258", - "revisionTime": "2016-08-11T22:07:13Z" + "revisionTime": "2016-08-11T22:07:13Z", + "version": "v3.2.0-beta", + "versionExact": "v3.2.0-beta" }, { - "checksumSHA1": "pi00alAztMy9MGxJmvg9qC+tsGk=", + "checksumSHA1": "eVSHe6GIHj9/ziFrQLZ1SC7Nn6k=", "comment": "v7.0.5", "path": "github.com/Azure/go-autorest/autorest", - "revision": "9c64b6583716b13caa7f85398c3331229c38f168", - "revisionTime": "2016-06-28T23:39:30Z" + "revision": "f0b1c4ee355163629bf0d9d52b7bef1d238f3426", + "revisionTime": "2016-08-11T21:24:34Z", + "version": "v7.1.0", + "versionExact": "v7.1.0" }, { - "checksumSHA1": "wP+cCq8z17Raoq9PndkX4J17W2w=", + "checksumSHA1": "z8FwqeLK0Pluo7FYC5k2MVBoils=", "comment": "v7.0.5", "path": "github.com/Azure/go-autorest/autorest/azure", - "revision": "9c64b6583716b13caa7f85398c3331229c38f168", - "revisionTime": "2016-06-28T23:39:30Z" + "revision": "f0b1c4ee355163629bf0d9d52b7bef1d238f3426", + "revisionTime": "2016-08-11T21:24:34Z", + "version": "v7.1.0", + "versionExact": "v7.1.0" }, { "checksumSHA1": "q4bSpJ5t571H3ny1PwIgTn6g75E=", "comment": "v7.0.5", "path": "github.com/Azure/go-autorest/autorest/date", - "revision": "9c64b6583716b13caa7f85398c3331229c38f168", - "revisionTime": "2016-06-28T23:39:30Z" + "revision": "f0b1c4ee355163629bf0d9d52b7bef1d238f3426", + "revisionTime": "2016-08-11T21:24:34Z", + "version": "v7.1.0", + "versionExact": "v7.1.0" }, { "checksumSHA1": "Ev8qCsbFjDlMlX0N2tYAhYQFpUc=", "comment": "v7.0.5", "path": "github.com/Azure/go-autorest/autorest/to", - "revision": "9c64b6583716b13caa7f85398c3331229c38f168", - "revisionTime": "2016-06-28T23:39:30Z" + "revision": "f0b1c4ee355163629bf0d9d52b7bef1d238f3426", + "revisionTime": "2016-08-11T21:24:34Z", + "version": "v7.1.0", + "versionExact": "v7.1.0" }, { "comment": "0.0.2-27-gedd0930", From 994ae08eb8dfe7fa6a464221ee8dadab9a1d1fc9 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Sat, 20 Aug 2016 10:16:03 +0100 Subject: [PATCH 056/100] provider/aws: Bump the AWS SDK version to 1.4.2 (#8285) --- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws/aws-sdk-go/service/apigateway/api.go | 2534 ++++++++++++++--- .../aws-sdk-go/service/apigateway/service.go | 10 +- .../aws/aws-sdk-go/service/ecs/api.go | 187 +- .../aws/aws-sdk-go/service/elbv2/api.go | 6 +- .../aws/aws-sdk-go/service/kms/api.go | 5 +- vendor/vendor.json | 425 ++- 7 files changed, 2606 insertions(+), 563 deletions(-) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 1fa57165f879..921a0e382cb5 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.4.1" +const SDKVersion = "1.4.2" diff --git a/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go b/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go index f0a48786d894..f97567a2540c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/apigateway/api.go @@ -54,6 +54,8 @@ func (c *APIGateway) CreateApiKeyRequest(input *CreateApiKeyInput) (req *request } // Create an ApiKey resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/create-api-key.html) func (c *APIGateway) CreateApiKey(input *CreateApiKeyInput) (*ApiKey, error) { req, out := c.CreateApiKeyRequest(input) err := req.Send() @@ -102,6 +104,8 @@ func (c *APIGateway) CreateAuthorizerRequest(input *CreateAuthorizerInput) (req } // Adds a new Authorizer resource to an existing RestApi resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) func (c *APIGateway) CreateAuthorizer(input *CreateAuthorizerInput) (*Authorizer, error) { req, out := c.CreateAuthorizerRequest(input) err := req.Send() @@ -446,6 +450,103 @@ func (c *APIGateway) CreateStage(input *CreateStageInput) (*Stage, error) { return out, err } +const opCreateUsagePlan = "CreateUsagePlan" + +// CreateUsagePlanRequest generates a "aws/request.Request" representing the +// client's request for the CreateUsagePlan operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateUsagePlan method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateUsagePlanRequest method. +// req, resp := client.CreateUsagePlanRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) CreateUsagePlanRequest(input *CreateUsagePlanInput) (req *request.Request, output *UsagePlan) { + op := &request.Operation{ + Name: opCreateUsagePlan, + HTTPMethod: "POST", + HTTPPath: "/usageplans", + } + + if input == nil { + input = &CreateUsagePlanInput{} + } + + req = c.newRequest(op, input, output) + output = &UsagePlan{} + req.Data = output + return +} + +// Creates a usage plan with the throttle and quota limits, as well as the associated +// API stages, specified in the payload. +func (c *APIGateway) CreateUsagePlan(input *CreateUsagePlanInput) (*UsagePlan, error) { + req, out := c.CreateUsagePlanRequest(input) + err := req.Send() + return out, err +} + +const opCreateUsagePlanKey = "CreateUsagePlanKey" + +// CreateUsagePlanKeyRequest generates a "aws/request.Request" representing the +// client's request for the CreateUsagePlanKey operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateUsagePlanKey method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateUsagePlanKeyRequest method. +// req, resp := client.CreateUsagePlanKeyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) CreateUsagePlanKeyRequest(input *CreateUsagePlanKeyInput) (req *request.Request, output *UsagePlanKey) { + op := &request.Operation{ + Name: opCreateUsagePlanKey, + HTTPMethod: "POST", + HTTPPath: "/usageplans/{usageplanId}/keys", + } + + if input == nil { + input = &CreateUsagePlanKeyInput{} + } + + req = c.newRequest(op, input, output) + output = &UsagePlanKey{} + req.Data = output + return +} + +// Creates a usage plan key for adding an existing API key to a usage plan. +func (c *APIGateway) CreateUsagePlanKey(input *CreateUsagePlanKeyInput) (*UsagePlanKey, error) { + req, out := c.CreateUsagePlanKeyRequest(input) + err := req.Send() + return out, err +} + const opDeleteApiKey = "DeleteApiKey" // DeleteApiKeyRequest generates a "aws/request.Request" representing the @@ -540,6 +641,8 @@ func (c *APIGateway) DeleteAuthorizerRequest(input *DeleteAuthorizerInput) (req } // Deletes an existing Authorizer resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/delete-authorizer.html) func (c *APIGateway) DeleteAuthorizer(input *DeleteAuthorizerInput) (*DeleteAuthorizerOutput, error) { req, out := c.DeleteAuthorizerRequest(input) err := req.Send() @@ -1147,6 +1250,107 @@ func (c *APIGateway) DeleteStage(input *DeleteStageInput) (*DeleteStageOutput, e return out, err } +const opDeleteUsagePlan = "DeleteUsagePlan" + +// DeleteUsagePlanRequest generates a "aws/request.Request" representing the +// client's request for the DeleteUsagePlan operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteUsagePlan method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteUsagePlanRequest method. +// req, resp := client.DeleteUsagePlanRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) DeleteUsagePlanRequest(input *DeleteUsagePlanInput) (req *request.Request, output *DeleteUsagePlanOutput) { + op := &request.Operation{ + Name: opDeleteUsagePlan, + HTTPMethod: "DELETE", + HTTPPath: "/usageplans/{usageplanId}", + } + + if input == nil { + input = &DeleteUsagePlanInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(restjson.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteUsagePlanOutput{} + req.Data = output + return +} + +// Deletes a usage plan of a given plan Id. +func (c *APIGateway) DeleteUsagePlan(input *DeleteUsagePlanInput) (*DeleteUsagePlanOutput, error) { + req, out := c.DeleteUsagePlanRequest(input) + err := req.Send() + return out, err +} + +const opDeleteUsagePlanKey = "DeleteUsagePlanKey" + +// DeleteUsagePlanKeyRequest generates a "aws/request.Request" representing the +// client's request for the DeleteUsagePlanKey operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteUsagePlanKey method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteUsagePlanKeyRequest method. +// req, resp := client.DeleteUsagePlanKeyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) DeleteUsagePlanKeyRequest(input *DeleteUsagePlanKeyInput) (req *request.Request, output *DeleteUsagePlanKeyOutput) { + op := &request.Operation{ + Name: opDeleteUsagePlanKey, + HTTPMethod: "DELETE", + HTTPPath: "/usageplans/{usageplanId}/keys/{keyId}", + } + + if input == nil { + input = &DeleteUsagePlanKeyInput{} + } + + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(restjson.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + output = &DeleteUsagePlanKeyOutput{} + req.Data = output + return +} + +// Deletes a usage plan key and remove the underlying API key from the associated +// usage plan. +func (c *APIGateway) DeleteUsagePlanKey(input *DeleteUsagePlanKeyInput) (*DeleteUsagePlanKeyOutput, error) { + req, out := c.DeleteUsagePlanKeyRequest(input) + err := req.Send() + return out, err +} + const opFlushStageAuthorizersCache = "FlushStageAuthorizersCache" // FlushStageAuthorizersCacheRequest generates a "aws/request.Request" representing the @@ -1512,6 +1716,8 @@ func (c *APIGateway) GetAuthorizerRequest(input *GetAuthorizerInput) (req *reque } // Describe an existing Authorizer resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-authorizer.html) func (c *APIGateway) GetAuthorizer(input *GetAuthorizerInput) (*Authorizer, error) { req, out := c.GetAuthorizerRequest(input) err := req.Send() @@ -1560,6 +1766,8 @@ func (c *APIGateway) GetAuthorizersRequest(input *GetAuthorizersInput) (req *req } // Describe an existing Authorizers resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-authorizers.html) func (c *APIGateway) GetAuthorizers(input *GetAuthorizersInput) (*GetAuthorizersOutput, error) { req, out := c.GetAuthorizersRequest(input) err := req.Send() @@ -2889,216 +3097,598 @@ func (c *APIGateway) GetStages(input *GetStagesInput) (*GetStagesOutput, error) return out, err } -const opImportRestApi = "ImportRestApi" +const opGetUsage = "GetUsage" -// ImportRestApiRequest generates a "aws/request.Request" representing the -// client's request for the ImportRestApi operation. The "output" return +// GetUsageRequest generates a "aws/request.Request" representing the +// client's request for the GetUsage operation. The "output" return // value can be used to capture response data after the request's "Send" method // is called. // // Creating a request object using this method should be used when you want to inject // custom logic into the request's lifecycle using a custom handler, or if you want to // access properties on the request object before or after sending the request. If -// you just want the service response, call the ImportRestApi method directly +// you just want the service response, call the GetUsage method directly // instead. // // Note: You must call the "Send" method on the returned request object in order // to execute the request. // -// // Example sending a request using the ImportRestApiRequest method. -// req, resp := client.ImportRestApiRequest(params) +// // Example sending a request using the GetUsageRequest method. +// req, resp := client.GetUsageRequest(params) // // err := req.Send() // if err == nil { // resp is now filled // fmt.Println(resp) // } // -func (c *APIGateway) ImportRestApiRequest(input *ImportRestApiInput) (req *request.Request, output *RestApi) { +func (c *APIGateway) GetUsageRequest(input *GetUsageInput) (req *request.Request, output *Usage) { op := &request.Operation{ - Name: opImportRestApi, - HTTPMethod: "POST", - HTTPPath: "/restapis?mode=import", + Name: opGetUsage, + HTTPMethod: "GET", + HTTPPath: "/usageplans/{usageplanId}/usage", + Paginator: &request.Paginator{ + InputTokens: []string{"position"}, + OutputTokens: []string{"position"}, + LimitToken: "limit", + TruncationToken: "", + }, } if input == nil { - input = &ImportRestApiInput{} + input = &GetUsageInput{} } req = c.newRequest(op, input, output) - output = &RestApi{} + output = &Usage{} req.Data = output return } -// A feature of the Amazon API Gateway control service for creating a new API -// from an external API definition file. -func (c *APIGateway) ImportRestApi(input *ImportRestApiInput) (*RestApi, error) { - req, out := c.ImportRestApiRequest(input) +// Gets the usage data of a usage plan in a specified time interval. +func (c *APIGateway) GetUsage(input *GetUsageInput) (*Usage, error) { + req, out := c.GetUsageRequest(input) err := req.Send() return out, err } -const opPutIntegration = "PutIntegration" +// GetUsagePages iterates over the pages of a GetUsage operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetUsage method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetUsage operation. +// pageNum := 0 +// err := client.GetUsagePages(params, +// func(page *Usage, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *APIGateway) GetUsagePages(input *GetUsageInput, fn func(p *Usage, lastPage bool) (shouldContinue bool)) error { + page, _ := c.GetUsageRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*Usage), lastPage) + }) +} -// PutIntegrationRequest generates a "aws/request.Request" representing the -// client's request for the PutIntegration operation. The "output" return +const opGetUsagePlan = "GetUsagePlan" + +// GetUsagePlanRequest generates a "aws/request.Request" representing the +// client's request for the GetUsagePlan operation. The "output" return // value can be used to capture response data after the request's "Send" method // is called. // // Creating a request object using this method should be used when you want to inject // custom logic into the request's lifecycle using a custom handler, or if you want to // access properties on the request object before or after sending the request. If -// you just want the service response, call the PutIntegration method directly +// you just want the service response, call the GetUsagePlan method directly // instead. // // Note: You must call the "Send" method on the returned request object in order // to execute the request. // -// // Example sending a request using the PutIntegrationRequest method. -// req, resp := client.PutIntegrationRequest(params) +// // Example sending a request using the GetUsagePlanRequest method. +// req, resp := client.GetUsagePlanRequest(params) // // err := req.Send() // if err == nil { // resp is now filled // fmt.Println(resp) // } // -func (c *APIGateway) PutIntegrationRequest(input *PutIntegrationInput) (req *request.Request, output *Integration) { +func (c *APIGateway) GetUsagePlanRequest(input *GetUsagePlanInput) (req *request.Request, output *UsagePlan) { op := &request.Operation{ - Name: opPutIntegration, - HTTPMethod: "PUT", - HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}/integration", + Name: opGetUsagePlan, + HTTPMethod: "GET", + HTTPPath: "/usageplans/{usageplanId}", } if input == nil { - input = &PutIntegrationInput{} + input = &GetUsagePlanInput{} } req = c.newRequest(op, input, output) - output = &Integration{} + output = &UsagePlan{} req.Data = output return } -// Represents a put integration. -func (c *APIGateway) PutIntegration(input *PutIntegrationInput) (*Integration, error) { - req, out := c.PutIntegrationRequest(input) +// Gets a usage plan of a given plan identifier. +func (c *APIGateway) GetUsagePlan(input *GetUsagePlanInput) (*UsagePlan, error) { + req, out := c.GetUsagePlanRequest(input) err := req.Send() return out, err } -const opPutIntegrationResponse = "PutIntegrationResponse" +const opGetUsagePlanKey = "GetUsagePlanKey" -// PutIntegrationResponseRequest generates a "aws/request.Request" representing the -// client's request for the PutIntegrationResponse operation. The "output" return +// GetUsagePlanKeyRequest generates a "aws/request.Request" representing the +// client's request for the GetUsagePlanKey operation. The "output" return // value can be used to capture response data after the request's "Send" method // is called. // // Creating a request object using this method should be used when you want to inject // custom logic into the request's lifecycle using a custom handler, or if you want to // access properties on the request object before or after sending the request. If -// you just want the service response, call the PutIntegrationResponse method directly +// you just want the service response, call the GetUsagePlanKey method directly // instead. // // Note: You must call the "Send" method on the returned request object in order // to execute the request. // -// // Example sending a request using the PutIntegrationResponseRequest method. -// req, resp := client.PutIntegrationResponseRequest(params) +// // Example sending a request using the GetUsagePlanKeyRequest method. +// req, resp := client.GetUsagePlanKeyRequest(params) // // err := req.Send() // if err == nil { // resp is now filled // fmt.Println(resp) // } // -func (c *APIGateway) PutIntegrationResponseRequest(input *PutIntegrationResponseInput) (req *request.Request, output *IntegrationResponse) { +func (c *APIGateway) GetUsagePlanKeyRequest(input *GetUsagePlanKeyInput) (req *request.Request, output *UsagePlanKey) { op := &request.Operation{ - Name: opPutIntegrationResponse, - HTTPMethod: "PUT", - HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}/integration/responses/{status_code}", + Name: opGetUsagePlanKey, + HTTPMethod: "GET", + HTTPPath: "/usageplans/{usageplanId}/keys/{keyId}", } if input == nil { - input = &PutIntegrationResponseInput{} + input = &GetUsagePlanKeyInput{} } req = c.newRequest(op, input, output) - output = &IntegrationResponse{} + output = &UsagePlanKey{} req.Data = output return } -// Represents a put integration. -func (c *APIGateway) PutIntegrationResponse(input *PutIntegrationResponseInput) (*IntegrationResponse, error) { - req, out := c.PutIntegrationResponseRequest(input) +// Gets a usage plan key of a given key identifier. +func (c *APIGateway) GetUsagePlanKey(input *GetUsagePlanKeyInput) (*UsagePlanKey, error) { + req, out := c.GetUsagePlanKeyRequest(input) err := req.Send() return out, err } -const opPutMethod = "PutMethod" +const opGetUsagePlanKeys = "GetUsagePlanKeys" -// PutMethodRequest generates a "aws/request.Request" representing the -// client's request for the PutMethod operation. The "output" return +// GetUsagePlanKeysRequest generates a "aws/request.Request" representing the +// client's request for the GetUsagePlanKeys operation. The "output" return // value can be used to capture response data after the request's "Send" method // is called. // // Creating a request object using this method should be used when you want to inject // custom logic into the request's lifecycle using a custom handler, or if you want to // access properties on the request object before or after sending the request. If -// you just want the service response, call the PutMethod method directly +// you just want the service response, call the GetUsagePlanKeys method directly // instead. // // Note: You must call the "Send" method on the returned request object in order // to execute the request. // -// // Example sending a request using the PutMethodRequest method. -// req, resp := client.PutMethodRequest(params) +// // Example sending a request using the GetUsagePlanKeysRequest method. +// req, resp := client.GetUsagePlanKeysRequest(params) // // err := req.Send() // if err == nil { // resp is now filled // fmt.Println(resp) // } // -func (c *APIGateway) PutMethodRequest(input *PutMethodInput) (req *request.Request, output *Method) { +func (c *APIGateway) GetUsagePlanKeysRequest(input *GetUsagePlanKeysInput) (req *request.Request, output *GetUsagePlanKeysOutput) { op := &request.Operation{ - Name: opPutMethod, - HTTPMethod: "PUT", - HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}", + Name: opGetUsagePlanKeys, + HTTPMethod: "GET", + HTTPPath: "/usageplans/{usageplanId}/keys", + Paginator: &request.Paginator{ + InputTokens: []string{"position"}, + OutputTokens: []string{"position"}, + LimitToken: "limit", + TruncationToken: "", + }, } if input == nil { - input = &PutMethodInput{} + input = &GetUsagePlanKeysInput{} } req = c.newRequest(op, input, output) - output = &Method{} + output = &GetUsagePlanKeysOutput{} req.Data = output return } -// Add a method to an existing Resource resource. -func (c *APIGateway) PutMethod(input *PutMethodInput) (*Method, error) { - req, out := c.PutMethodRequest(input) +// Gets all the usage plan keys representing the API keys added to a specified +// usage plan. +func (c *APIGateway) GetUsagePlanKeys(input *GetUsagePlanKeysInput) (*GetUsagePlanKeysOutput, error) { + req, out := c.GetUsagePlanKeysRequest(input) err := req.Send() return out, err } -const opPutMethodResponse = "PutMethodResponse" - -// PutMethodResponseRequest generates a "aws/request.Request" representing the -// client's request for the PutMethodResponse operation. The "output" return -// value can be used to capture response data after the request's "Send" method -// is called. +// GetUsagePlanKeysPages iterates over the pages of a GetUsagePlanKeys operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. // -// Creating a request object using this method should be used when you want to inject -// custom logic into the request's lifecycle using a custom handler, or if you want to -// access properties on the request object before or after sending the request. If -// you just want the service response, call the PutMethodResponse method directly -// instead. +// See GetUsagePlanKeys method for more information on how to use this operation. // -// Note: You must call the "Send" method on the returned request object in order -// to execute the request. +// Note: This operation can generate multiple requests to a service. // -// // Example sending a request using the PutMethodResponseRequest method. +// // Example iterating over at most 3 pages of a GetUsagePlanKeys operation. +// pageNum := 0 +// err := client.GetUsagePlanKeysPages(params, +// func(page *GetUsagePlanKeysOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *APIGateway) GetUsagePlanKeysPages(input *GetUsagePlanKeysInput, fn func(p *GetUsagePlanKeysOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.GetUsagePlanKeysRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*GetUsagePlanKeysOutput), lastPage) + }) +} + +const opGetUsagePlans = "GetUsagePlans" + +// GetUsagePlansRequest generates a "aws/request.Request" representing the +// client's request for the GetUsagePlans operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetUsagePlans method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetUsagePlansRequest method. +// req, resp := client.GetUsagePlansRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) GetUsagePlansRequest(input *GetUsagePlansInput) (req *request.Request, output *GetUsagePlansOutput) { + op := &request.Operation{ + Name: opGetUsagePlans, + HTTPMethod: "GET", + HTTPPath: "/usageplans", + Paginator: &request.Paginator{ + InputTokens: []string{"position"}, + OutputTokens: []string{"position"}, + LimitToken: "limit", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetUsagePlansInput{} + } + + req = c.newRequest(op, input, output) + output = &GetUsagePlansOutput{} + req.Data = output + return +} + +// Gets all the usage plans of the caller's account. +func (c *APIGateway) GetUsagePlans(input *GetUsagePlansInput) (*GetUsagePlansOutput, error) { + req, out := c.GetUsagePlansRequest(input) + err := req.Send() + return out, err +} + +// GetUsagePlansPages iterates over the pages of a GetUsagePlans operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetUsagePlans method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetUsagePlans operation. +// pageNum := 0 +// err := client.GetUsagePlansPages(params, +// func(page *GetUsagePlansOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *APIGateway) GetUsagePlansPages(input *GetUsagePlansInput, fn func(p *GetUsagePlansOutput, lastPage bool) (shouldContinue bool)) error { + page, _ := c.GetUsagePlansRequest(input) + page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator")) + return page.EachPage(func(p interface{}, lastPage bool) bool { + return fn(p.(*GetUsagePlansOutput), lastPage) + }) +} + +const opImportApiKeys = "ImportApiKeys" + +// ImportApiKeysRequest generates a "aws/request.Request" representing the +// client's request for the ImportApiKeys operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportApiKeys method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportApiKeysRequest method. +// req, resp := client.ImportApiKeysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) ImportApiKeysRequest(input *ImportApiKeysInput) (req *request.Request, output *ImportApiKeysOutput) { + op := &request.Operation{ + Name: opImportApiKeys, + HTTPMethod: "POST", + HTTPPath: "/apikeys?mode=import", + } + + if input == nil { + input = &ImportApiKeysInput{} + } + + req = c.newRequest(op, input, output) + output = &ImportApiKeysOutput{} + req.Data = output + return +} + +// Import API keys from an external source, such as a CSV-formatted file. +func (c *APIGateway) ImportApiKeys(input *ImportApiKeysInput) (*ImportApiKeysOutput, error) { + req, out := c.ImportApiKeysRequest(input) + err := req.Send() + return out, err +} + +const opImportRestApi = "ImportRestApi" + +// ImportRestApiRequest generates a "aws/request.Request" representing the +// client's request for the ImportRestApi operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ImportRestApi method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ImportRestApiRequest method. +// req, resp := client.ImportRestApiRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) ImportRestApiRequest(input *ImportRestApiInput) (req *request.Request, output *RestApi) { + op := &request.Operation{ + Name: opImportRestApi, + HTTPMethod: "POST", + HTTPPath: "/restapis?mode=import", + } + + if input == nil { + input = &ImportRestApiInput{} + } + + req = c.newRequest(op, input, output) + output = &RestApi{} + req.Data = output + return +} + +// A feature of the Amazon API Gateway control service for creating a new API +// from an external API definition file. +func (c *APIGateway) ImportRestApi(input *ImportRestApiInput) (*RestApi, error) { + req, out := c.ImportRestApiRequest(input) + err := req.Send() + return out, err +} + +const opPutIntegration = "PutIntegration" + +// PutIntegrationRequest generates a "aws/request.Request" representing the +// client's request for the PutIntegration operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PutIntegration method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PutIntegrationRequest method. +// req, resp := client.PutIntegrationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) PutIntegrationRequest(input *PutIntegrationInput) (req *request.Request, output *Integration) { + op := &request.Operation{ + Name: opPutIntegration, + HTTPMethod: "PUT", + HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}/integration", + } + + if input == nil { + input = &PutIntegrationInput{} + } + + req = c.newRequest(op, input, output) + output = &Integration{} + req.Data = output + return +} + +// Represents a put integration. +func (c *APIGateway) PutIntegration(input *PutIntegrationInput) (*Integration, error) { + req, out := c.PutIntegrationRequest(input) + err := req.Send() + return out, err +} + +const opPutIntegrationResponse = "PutIntegrationResponse" + +// PutIntegrationResponseRequest generates a "aws/request.Request" representing the +// client's request for the PutIntegrationResponse operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PutIntegrationResponse method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PutIntegrationResponseRequest method. +// req, resp := client.PutIntegrationResponseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) PutIntegrationResponseRequest(input *PutIntegrationResponseInput) (req *request.Request, output *IntegrationResponse) { + op := &request.Operation{ + Name: opPutIntegrationResponse, + HTTPMethod: "PUT", + HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}/integration/responses/{status_code}", + } + + if input == nil { + input = &PutIntegrationResponseInput{} + } + + req = c.newRequest(op, input, output) + output = &IntegrationResponse{} + req.Data = output + return +} + +// Represents a put integration. +func (c *APIGateway) PutIntegrationResponse(input *PutIntegrationResponseInput) (*IntegrationResponse, error) { + req, out := c.PutIntegrationResponseRequest(input) + err := req.Send() + return out, err +} + +const opPutMethod = "PutMethod" + +// PutMethodRequest generates a "aws/request.Request" representing the +// client's request for the PutMethod operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PutMethod method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PutMethodRequest method. +// req, resp := client.PutMethodRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) PutMethodRequest(input *PutMethodInput) (req *request.Request, output *Method) { + op := &request.Operation{ + Name: opPutMethod, + HTTPMethod: "PUT", + HTTPPath: "/restapis/{restapi_id}/resources/{resource_id}/methods/{http_method}", + } + + if input == nil { + input = &PutMethodInput{} + } + + req = c.newRequest(op, input, output) + output = &Method{} + req.Data = output + return +} + +// Add a method to an existing Resource resource. +func (c *APIGateway) PutMethod(input *PutMethodInput) (*Method, error) { + req, out := c.PutMethodRequest(input) + err := req.Send() + return out, err +} + +const opPutMethodResponse = "PutMethodResponse" + +// PutMethodResponseRequest generates a "aws/request.Request" representing the +// client's request for the PutMethodResponse operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PutMethodResponse method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PutMethodResponseRequest method. // req, resp := client.PutMethodResponseRequest(params) // // err := req.Send() @@ -3224,6 +3814,8 @@ func (c *APIGateway) TestInvokeAuthorizerRequest(input *TestInvokeAuthorizerInpu // Simulate the execution of an Authorizer in your RestApi with headers, parameters, // and an incoming request body. +// +// Enable custom authorizers (http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html) func (c *APIGateway) TestInvokeAuthorizer(input *TestInvokeAuthorizerInput) (*TestInvokeAuthorizerOutput, error) { req, out := c.TestInvokeAuthorizerRequest(input) err := req.Send() @@ -3417,6 +4009,8 @@ func (c *APIGateway) UpdateAuthorizerRequest(input *UpdateAuthorizerInput) (req } // Updates an existing Authorizer resource. +// +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/update-authorizer.html) func (c *APIGateway) UpdateAuthorizer(input *UpdateAuthorizerInput) (*Authorizer, error) { req, out := c.UpdateAuthorizerRequest(input) err := req.Send() @@ -3999,16 +4593,150 @@ func (c *APIGateway) UpdateStage(input *UpdateStageInput) (*Stage, error) { return out, err } +const opUpdateUsage = "UpdateUsage" + +// UpdateUsageRequest generates a "aws/request.Request" representing the +// client's request for the UpdateUsage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the UpdateUsage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the UpdateUsageRequest method. +// req, resp := client.UpdateUsageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) UpdateUsageRequest(input *UpdateUsageInput) (req *request.Request, output *Usage) { + op := &request.Operation{ + Name: opUpdateUsage, + HTTPMethod: "PATCH", + HTTPPath: "/usageplans/{usageplanId}/keys/{keyId}/usage", + } + + if input == nil { + input = &UpdateUsageInput{} + } + + req = c.newRequest(op, input, output) + output = &Usage{} + req.Data = output + return +} + +// Grants a temporary extension to the reamining quota of a usage plan associated +// with a specified API key. +func (c *APIGateway) UpdateUsage(input *UpdateUsageInput) (*Usage, error) { + req, out := c.UpdateUsageRequest(input) + err := req.Send() + return out, err +} + +const opUpdateUsagePlan = "UpdateUsagePlan" + +// UpdateUsagePlanRequest generates a "aws/request.Request" representing the +// client's request for the UpdateUsagePlan operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the UpdateUsagePlan method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the UpdateUsagePlanRequest method. +// req, resp := client.UpdateUsagePlanRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +func (c *APIGateway) UpdateUsagePlanRequest(input *UpdateUsagePlanInput) (req *request.Request, output *UsagePlan) { + op := &request.Operation{ + Name: opUpdateUsagePlan, + HTTPMethod: "PATCH", + HTTPPath: "/usageplans/{usageplanId}", + } + + if input == nil { + input = &UpdateUsagePlanInput{} + } + + req = c.newRequest(op, input, output) + output = &UsagePlan{} + req.Data = output + return +} + +// Updates a usage plan of a given plan Id. +func (c *APIGateway) UpdateUsagePlan(input *UpdateUsagePlanInput) (*UsagePlan, error) { + req, out := c.UpdateUsagePlanRequest(input) + err := req.Send() + return out, err +} + // Represents an AWS account that is associated with Amazon API Gateway. +// +// To view the account info, call GET on this resource. +// +// Error Codes +// +// The following exception may be thrown when the request fails. +// +// UnauthorizedException NotFoundException TooManyRequestsException For detailed +// error code information, including the corresponding HTTP Status Codes, see +// API Gateway Error Codes (http://docs.aws.amazon.com/apigateway/api-reference/handling-errors/#api-error-codes) +// +// Example: Get the information about an account. +// +// Request +// +// GET /account HTTP/1.1 Content-Type: application/json Host: apigateway.us-east-1.amazonaws.com +// X-Amz-Date: 20160531T184618Z Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/us-east-1/apigateway/aws4_request, +// SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response +// +// The successful response returns a 200 OK status code and a payload similar +// to the following: +// +// { "_links": { "curies": { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/account-apigateway-{rel}.html", +// "name": "account", "templated": true }, "self": { "href": "/account" }, "account:update": +// { "href": "/account" } }, "cloudwatchRoleArn": "arn:aws:iam::123456789012:role/apigAwsProxyRole", +// "throttleSettings": { "rateLimit": 500, "burstLimit": 1000 } } In addition +// to making the REST API call directly, you can use the AWS CLI and an AWS +// SDK to access this resource. +// +// API Gateway Limits (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-limits.html) +// Developer Guide (http://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html), +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-account.html) type Account struct { _ struct{} `type:"structure"` - // Specifies the Amazon resource name (ARN) of an Amazon CloudWatch role for - // the current Account resource. + // The version of the API keys used for the account. + ApiKeyVersion *string `locationName:"apiKeyVersion" type:"string"` + + // The ARN of an Amazon CloudWatch role for the current Account. CloudwatchRoleArn *string `locationName:"cloudwatchRoleArn" type:"string"` - // Specifies the application programming interface (API) throttle settings for - // the current Account resource. + // A list of features supported for the account. When usage plans are enabled, + // the features list will include an entry of "UsagePlans". + Features []*string `locationName:"features" type:"list"` + + // Specifies the API request limits configured for the current Account. ThrottleSettings *ThrottleSettings `locationName:"throttleSettings" type:"structure"` } @@ -4026,6 +4754,8 @@ func (s Account) GoString() string { // that require an API key. API keys can be mapped to any Stage on any RestApi, // which indicates that the callers with the API key can make requests to that // stage. +// +// Use API Keys (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-api-keys.html) type ApiKey struct { _ struct{} `type:"structure"` @@ -4050,6 +4780,9 @@ type ApiKey struct { // A list of Stage resources that are associated with the ApiKey resource. StageKeys []*string `locationName:"stageKeys" type:"list"` + + // The value of the API Key. + Value *string `locationName:"value" type:"string"` } // String returns the string representation @@ -4062,8 +4795,31 @@ func (s ApiKey) GoString() string { return s.String() } +// API stage name of the associated API stage in a usage plan. +type ApiStage struct { + _ struct{} `type:"structure"` + + // API Id of the associated API stage in a usage plan. + ApiId *string `locationName:"apiId" type:"string"` + + // API stage name of the associated API stage in a usage plan. + Stage *string `locationName:"stage" type:"string"` +} + +// String returns the string representation +func (s ApiStage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ApiStage) GoString() string { + return s.String() +} + // Represents an authorization layer for methods. If enabled on a method, API // Gateway will activate the authorizer when a client calls the method. +// +// Enable custom authorization (http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html) type Authorizer struct { _ struct{} `type:"structure"` @@ -4072,7 +4828,7 @@ type Authorizer struct { AuthType *string `locationName:"authType" type:"string"` // Specifies the credentials required for the authorizer, if any. Two options - // are available. To specify an IAM Role for Amazon API Gateway to assume, use + // are available. To specify an IAM role for Amazon API Gateway to assume, use // the role's Amazon Resource Name (ARN). To use resource-based permissions // on the Lambda function, specify null. AuthorizerCredentials *string `locationName:"authorizerCredentials" type:"string"` @@ -4110,6 +4866,7 @@ type Authorizer struct { // [Required] The name of the authorizer. Name *string `locationName:"name" type:"string"` + // A list of the provider ARNs of the authorizer. ProviderARNs []*string `locationName:"providerARNs" type:"list"` // [Required] The type of the authorizer. Currently, the only valid type is @@ -4127,8 +4884,11 @@ func (s Authorizer) GoString() string { return s.String() } -// Represents the base path that callers of the API that must provide as part -// of the URL after the domain name. +// Represents the base path that callers of the API must provide as part of +// the URL after the domain name. +// +// A custom domain name plus a BasePathMapping specification identifies a deployed +// RestApi in a given stage of the owner Account. Use Custom Domain Names (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) type BasePathMapping struct { _ struct{} `type:"structure"` @@ -4153,26 +4913,30 @@ func (s BasePathMapping) GoString() string { return s.String() } -// Represents a Client Certificate used to configure client-side SSL authentication +// Represents a client certificate used to configure client-side SSL authentication // while sending requests to the integration endpoint. +// +// Client certificates are used authenticate an API by the back-end server. +// To authenticate an API client (or user), use a custom Authorizer. Use Client-Side +// Certificate (http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html) type ClientCertificate struct { _ struct{} `type:"structure"` - // The identifier of the Client Certificate. + // The identifier of the client certificate. ClientCertificateId *string `locationName:"clientCertificateId" type:"string"` - // The date when the Client Certificate was created, in ISO 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" + // The date when the client certificate was created, in ISO 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" // target="_blank). CreatedDate *time.Time `locationName:"createdDate" type:"timestamp" timestampFormat:"unix"` - // The description of the Client Certificate. + // The description of the client certificate. Description *string `locationName:"description" type:"string"` - // The date when the Client Certificate will expire, in ISO 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" + // The date when the client certificate will expire, in ISO 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" // target="_blank). ExpirationDate *time.Time `locationName:"expirationDate" type:"timestamp" timestampFormat:"unix"` - // The PEM-encoded public key of the Client Certificate, that can be used to + // The PEM-encoded public key of the client certificate, which can be used to // configure certificate authentication in the integration endpoint . PemEncodedCertificate *string `locationName:"pemEncodedCertificate" type:"string"` } @@ -4197,11 +4961,18 @@ type CreateApiKeyInput struct { // Specifies whether the ApiKey can be used by callers. Enabled *bool `locationName:"enabled" type:"boolean"` + // Specifies whether (true) or not (false) the key identifier is distinct from + // the created API key value. + GenerateDistinctId *bool `locationName:"generateDistinctId" type:"boolean"` + // The name of the ApiKey. Name *string `locationName:"name" type:"string"` - // Specifies whether the ApiKey can be used by callers. + // DEPRECATED FOR USAGE PLANS - Specifies stages associated with the API key. StageKeys []*StageKey `locationName:"stageKeys" type:"list"` + + // Specifies a value of the API key. + Value *string `locationName:"value" type:"string"` } // String returns the string representation @@ -4240,6 +5011,7 @@ type CreateAuthorizerInput struct { // [Required] The name of the authorizer. Name *string `locationName:"name" type:"string" required:"true"` + // A list of the Cognito Your User Pool authorizer's provider ARNs. ProviderARNs []*string `locationName:"providerARNs" type:"list"` // The RestApi identifier under which the Authorizer will be created. @@ -4353,8 +5125,8 @@ type CreateDeploymentInput struct { StageName *string `locationName:"stageName" type:"string" required:"true"` // A map that defines the stage variables for the Stage resource that is associated - // with the new deployment. Variable names can have alphanumeric characters, - // and the values must match [A-Za-z0-9-._~:/?#&=,]+. + // with the new deployment. Variable names can have alphanumeric and underscore + // characters, and the values must match [A-Za-z0-9-._~:/?#&=,]+. Variables map[string]*string `locationName:"variables" type:"map"` } @@ -4541,7 +5313,7 @@ func (s *CreateResourceInput) Validate() error { type CreateRestApiInput struct { _ struct{} `type:"structure"` - // The Id of the RestApi that you want to clone from. + // The ID of the RestApi that you want to clone from. CloneFrom *string `locationName:"cloneFrom" type:"string"` // The description of the RestApi. @@ -4597,7 +5369,8 @@ type CreateStageInput struct { StageName *string `locationName:"stageName" type:"string" required:"true"` // A map that defines the stage variables for the new Stage resource. Variable - // names can have alphanumeric characters, and the values must match [A-Za-z0-9-._~:/?#&=,]+. + // names can have alphanumeric and underscore characters, and the values must + // match [A-Za-z0-9-._~:/?#&=,]+. Variables map[string]*string `locationName:"variables" type:"map"` } @@ -4630,6 +5403,96 @@ func (s *CreateStageInput) Validate() error { return nil } +// The POST request to create a usage plan with the name, description, throttle +// limits and quota limits, as well as the associated API stages, specified +// in the payload. +type CreateUsagePlanInput struct { + _ struct{} `type:"structure"` + + // The associated API stages of the usage plan. + ApiStages []*ApiStage `locationName:"apiStages" type:"list"` + + // The description of the usage plan. + Description *string `locationName:"description" type:"string"` + + // The name of the usage plan. + Name *string `locationName:"name" type:"string" required:"true"` + + // The quota of the usage plan. + Quota *QuotaSettings `locationName:"quota" type:"structure"` + + // The throttling limits of the usage plan. + Throttle *ThrottleSettings `locationName:"throttle" type:"structure"` +} + +// String returns the string representation +func (s CreateUsagePlanInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateUsagePlanInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateUsagePlanInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateUsagePlanInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The POST request to create a usage plan key for adding an existing API key +// to a usage plan. +type CreateUsagePlanKeyInput struct { + _ struct{} `type:"structure"` + + // The identifier of a UsagePlanKey resource for a plan customer. + KeyId *string `locationName:"keyId" type:"string" required:"true"` + + // The type of a UsagePlanKey resource for a plan customer. + KeyType *string `locationName:"keyType" type:"string" required:"true"` + + // The Id of the UsagePlan resource representing the usage plan containing the + // to-be-created UsagePlanKey resource representing a plan customer. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateUsagePlanKeyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateUsagePlanKeyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateUsagePlanKeyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateUsagePlanKeyInput"} + if s.KeyId == nil { + invalidParams.Add(request.NewErrParamRequired("KeyId")) + } + if s.KeyType == nil { + invalidParams.Add(request.NewErrParamRequired("KeyType")) + } + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + // A request to delete the ApiKey resource. type DeleteApiKeyInput struct { _ struct{} `type:"structure"` @@ -5042,7 +5905,7 @@ func (s DeleteIntegrationResponseOutput) GoString() string { type DeleteMethodInput struct { _ struct{} `type:"structure"` - // The HTTP verb that identifies the Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // The Resource identifier for the Method resource. @@ -5099,7 +5962,7 @@ func (s DeleteMethodOutput) GoString() string { type DeleteMethodResponseInput struct { _ struct{} `type:"structure"` - // The HTTP verb identifier for the parent Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // The Resource identifier for the MethodResponse resource. @@ -5336,33 +6199,137 @@ func (s *DeleteStageInput) Validate() error { invalidParams.Add(request.NewErrParamRequired("StageName")) } - if invalidParams.Len() > 0 { - return invalidParams - } - return nil + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteStageOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteStageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteStageOutput) GoString() string { + return s.String() +} + +// The DELETE request to delete a uasge plan of a given plan Id. +type DeleteUsagePlanInput struct { + _ struct{} `type:"structure"` + + // The Id of the to-be-deleted usage plan. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteUsagePlanInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteUsagePlanInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteUsagePlanInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteUsagePlanInput"} + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The DELETE request to delete a usage plan key and remove the underlying API +// key from the associated usage plan. +type DeleteUsagePlanKeyInput struct { + _ struct{} `type:"structure"` + + // The Id of the UsagePlanKey resource to be deleted. + KeyId *string `location:"uri" locationName:"keyId" type:"string" required:"true"` + + // The Id of the UsagePlan resource representing the usage plan containing the + // to-be-deleted UsagePlanKey resource representing a plan customer. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteUsagePlanKeyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteUsagePlanKeyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteUsagePlanKeyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteUsagePlanKeyInput"} + if s.KeyId == nil { + invalidParams.Add(request.NewErrParamRequired("KeyId")) + } + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +type DeleteUsagePlanKeyOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteUsagePlanKeyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteUsagePlanKeyOutput) GoString() string { + return s.String() } -type DeleteStageOutput struct { +type DeleteUsagePlanOutput struct { _ struct{} `type:"structure"` } // String returns the string representation -func (s DeleteStageOutput) String() string { +func (s DeleteUsagePlanOutput) String() string { return awsutil.Prettify(s) } // GoString returns the string representation -func (s DeleteStageOutput) GoString() string { +func (s DeleteUsagePlanOutput) GoString() string { return s.String() } // An immutable representation of a RestApi resource that can be called by users // using Stages. A deployment must be associated with a Stage for it to be callable // over the Internet. +// +// To create a deployment, call POST on the Deployments resource of a RestApi. +// To view, update, or delete a deployment, call GET, PATCH, or DELETE on the +// specified deployment resource (/restapis/{restapi_id}/deployments/{deployment_id}). +// RestApi, Deployments, Stage, AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-deployment.html), +// AWS SDKs (https://aws.amazon.com/tools/) type Deployment struct { _ struct{} `type:"structure"` - // Gets a summary of the RestApi at the date and time that the deployment resource + // A summary of the RestApi at the date and time that the deployment resource // was created. ApiSummary map[string]map[string]*MethodSnapshot `locationName:"apiSummary" type:"map"` @@ -5388,6 +6355,8 @@ func (s Deployment) GoString() string { // Represents a domain name that is contained in a simpler, more intuitive URL // that can be called. +// +// Use Client-Side Certificate (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) type DomainName struct { _ struct{} `type:"structure"` @@ -5559,6 +6528,10 @@ type GetApiKeyInput struct { // The identifier of the ApiKey resource. ApiKey *string `location:"uri" locationName:"api_Key" type:"string" required:"true"` + + // A boolean flag to specify whether (true) or not (false) the result contains + // the key value. + IncludeValue *bool `location:"querystring" locationName:"includeValue" type:"boolean"` } // String returns the string representation @@ -5588,9 +6561,16 @@ func (s *GetApiKeyInput) Validate() error { type GetApiKeysInput struct { _ struct{} `type:"structure"` + // A boolean flag to specify whether (true) or not (false) the result contains + // key values. + IncludeValues *bool `location:"querystring" locationName:"includeValues" type:"boolean"` + // The maximum number of ApiKeys to get information about. Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` + // The name of queried API keys. + NameQuery *string `location:"querystring" locationName:"name" type:"string"` + // The position of the current ApiKeys resource to get information about. Position *string `location:"querystring" locationName:"position" type:"string"` } @@ -5605,7 +6585,9 @@ func (s GetApiKeysInput) GoString() string { return s.String() } -// Represents a collection of ApiKey resources. +// Represents a collection of API keys as represented by an ApiKeys resource. +// +// Use API Keys (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-api-keys.html) type GetApiKeysOutput struct { _ struct{} `type:"structure"` @@ -5613,6 +6595,10 @@ type GetApiKeysOutput struct { Items []*ApiKey `locationName:"item" type:"list"` Position *string `locationName:"position" type:"string"` + + // A list of warning messages logged during the import of API keys when the + // failOnWarnings option is set to true. + Warnings []*string `locationName:"warnings" type:"list"` } // String returns the string representation @@ -5670,7 +6656,7 @@ type GetAuthorizersInput struct { Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` // If not all Authorizer resources in the response were present, the position - // will specificy where to start the next page of results. + // will specify where to start the next page of results. Position *string `location:"querystring" locationName:"position" type:"string"` // The RestApi identifier for the Authorizers resource. @@ -5701,6 +6687,8 @@ func (s *GetAuthorizersInput) Validate() error { } // Represents a collection of Authorizer resources. +// +// Enable custom authorization (http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html) type GetAuthorizersOutput struct { _ struct{} `type:"structure"` @@ -5801,6 +6789,8 @@ func (s *GetBasePathMappingsInput) Validate() error { } // Represents a collection of BasePathMapping resources. +// +// Use Custom Domain Names (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) type GetBasePathMappingsOutput struct { _ struct{} `type:"structure"` @@ -5877,6 +6867,8 @@ func (s GetClientCertificatesInput) GoString() string { } // Represents a collection of ClientCertificate resources. +// +// Use Client-Side Certificate (http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html) type GetClientCertificatesOutput struct { _ struct{} `type:"structure"` @@ -5976,9 +6968,16 @@ func (s *GetDeploymentsInput) Validate() error { } // Represents a collection resource that contains zero or more references to -// your existing deployments, and links that guide you on ways to interact with +// your existing deployments, and links that guide you on how to interact with // your collection. The collection offers a paginated view of the contained // deployments. +// +// To create a new deployment of a RestApi, make a POST request against this +// resource. To view, update, or delete an existing deployment, make a GET, +// PATCH, or DELETE request, respectively, on a specified Deployment resource. +// Deploying an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html), +// AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-deployment.html), +// AWS SDKs (https://aws.amazon.com/tools/) type GetDeploymentsOutput struct { _ struct{} `type:"structure"` @@ -6053,6 +7052,8 @@ func (s GetDomainNamesInput) GoString() string { } // Represents a collection of DomainName resources. +// +// Use Client-Side Certificate (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) type GetDomainNamesOutput struct { _ struct{} `type:"structure"` @@ -6077,20 +7078,21 @@ func (s GetDomainNamesOutput) GoString() string { type GetExportInput struct { _ struct{} `type:"structure"` - // The content-type of the export, for example 'application/json'. Currently - // 'application/json' and 'application/yaml' are supported for exportType 'swagger'. - // Should be specifed in the 'Accept' header for direct API requests. + // The content-type of the export, for example application/json. Currently application/json + // and application/yaml are supported for exportType of swagger. This should + // be specified in the Accept header for direct API requests. Accepts *string `location:"header" locationName:"Accept" type:"string"` // The type of export. Currently only 'swagger' is supported. ExportType *string `location:"uri" locationName:"export_type" type:"string" required:"true"` // A key-value map of query string parameters that specify properties of the - // export, depending on the requested exportType. For exportType 'swagger', - // any combination of the following parameters are supported: 'integrations' - // will export x-amazon-apigateway-integration extensions 'authorizers' will - // export x-amazon-apigateway-authorizer extensions 'postman' will export with - // Postman extensions, allowing for import to the Postman tool + // export, depending on the requested exportType. For exportType swagger, any + // combination of the following parameters are supported: integrations will + // export the API with x-amazon-apigateway-integration extensions. authorizers + // will export the API with x-amazon-apigateway-authorizer extensions. postman + // will export the API with Postman extensions, allowing for import to the Postman + // tool Parameters map[string]*string `location:"querystring" locationName:"parameters" type:"map"` // The identifier of the RestApi to be exported. @@ -6136,7 +7138,7 @@ type GetExportOutput struct { // The binary blob response to GetExport, which contains the export. Body []byte `locationName:"body" type:"blob"` - // The content-disposition header value in the HTTP reseponse. + // The content-disposition header value in the HTTP response. ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"` // The content-type header value in the HTTP response. This will correspond @@ -6250,7 +7252,7 @@ func (s *GetIntegrationResponseInput) Validate() error { type GetMethodInput struct { _ struct{} `type:"structure"` - // Specifies the put method request's HTTP method type. + // Specifies the method request's HTTP method type. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // The Resource identifier for the Method resource. @@ -6293,7 +7295,7 @@ func (s *GetMethodInput) Validate() error { type GetMethodResponseInput struct { _ struct{} `type:"structure"` - // The HTTP verb identifier for the parent Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // The Resource identifier for the MethodResponse resource. @@ -6302,7 +7304,7 @@ type GetMethodResponseInput struct { // The RestApi identifier for the MethodResponse resource. RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` - // The status code identifier for the MethodResponse resource. + // The status code for the MethodResponse resource. StatusCode *string `location:"uri" locationName:"status_code" type:"string" required:"true"` } @@ -6342,7 +7344,9 @@ func (s *GetMethodResponseInput) Validate() error { type GetModelInput struct { _ struct{} `type:"structure"` - // Resolves all external model references and returns a flattened model schema. + // A query parameter of a Boolean value to resolve (true) all external model + // references and returns a flattened model schema or not (false) The default + // is false. Flatten *bool `location:"querystring" locationName:"flatten" type:"boolean"` // The name of the model as an identifier. @@ -6416,6 +7420,8 @@ func (s *GetModelTemplateInput) Validate() error { } // Represents a mapping template used to transform a payload. +// +// Mapping Templates (http://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html#models-mappings-mappings) type GetModelTemplateOutput struct { _ struct{} `type:"structure"` @@ -6474,6 +7480,8 @@ func (s *GetModelsInput) Validate() error { } // Represents a collection of Model resources. +// +// Method, MethodResponse, Models and Mappings (http://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html) type GetModelsOutput struct { _ struct{} `type:"structure"` @@ -6570,6 +7578,8 @@ func (s *GetResourcesInput) Validate() error { } // Represents a collection of Resource resources. +// +// Create an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type GetResourcesOutput struct { _ struct{} `type:"structure"` @@ -6643,8 +7653,10 @@ func (s GetRestApisInput) GoString() string { return s.String() } -// Contains references to your APIs and links that guide you in ways to interact +// Contains references to your APIs and links that guide you in how to interact // with your collection. A collection offers a paginated view of your APIs. +// +// Create an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type GetRestApisOutput struct { _ struct{} `type:"structure"` @@ -6669,9 +7681,9 @@ type GetSdkInput struct { _ struct{} `type:"structure"` // A key-value map of query string parameters that specify properties of the - // SDK, depending on the requested sdkType. For sdkType 'objectivec', a parameter - // named "classPrefix" is required. For sdkType 'android', parameters named - // "groupId", "artifactId", "artifactVersion", and "invokerPackage" are required. + // SDK, depending on the requested sdkType. For sdkType of objectivec, a parameter + // named classPrefix is required. For sdkType of android, parameters named groupId, + // artifactId, artifactVersion, and invokerPackage are required. Parameters map[string]*string `location:"querystring" locationName:"parameters" type:"map"` // The identifier of the RestApi that the SDK will use. @@ -6708,100 +7720,401 @@ func (s *GetSdkInput) Validate() error { invalidParams.Add(request.NewErrParamRequired("StageName")) } - if invalidParams.Len() > 0 { - return invalidParams - } - return nil + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The binary blob response to GetSdk, which contains the generated SDK. +type GetSdkOutput struct { + _ struct{} `type:"structure" payload:"Body"` + + // The binary blob response to GetSdk, which contains the generated SDK. + Body []byte `locationName:"body" type:"blob"` + + // The content-disposition header value in the HTTP response. + ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"` + + // The content-type header value in the HTTP response. + ContentType *string `location:"header" locationName:"Content-Type" type:"string"` +} + +// String returns the string representation +func (s GetSdkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSdkOutput) GoString() string { + return s.String() +} + +// Requests Amazon API Gateway to get information about a Stage resource. +type GetStageInput struct { + _ struct{} `type:"structure"` + + // The identifier of the RestApi resource for the Stage resource to get information + // about. + RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` + + // The name of the Stage resource to get information about. + StageName *string `location:"uri" locationName:"stage_name" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetStageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetStageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetStageInput"} + if s.RestApiId == nil { + invalidParams.Add(request.NewErrParamRequired("RestApiId")) + } + if s.StageName == nil { + invalidParams.Add(request.NewErrParamRequired("StageName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Requests Amazon API Gateway to get information about one or more Stage resources. +type GetStagesInput struct { + _ struct{} `type:"structure"` + + // The stages' deployment identifiers. + DeploymentId *string `location:"querystring" locationName:"deploymentId" type:"string"` + + // The stages' API identifiers. + RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetStagesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStagesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetStagesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetStagesInput"} + if s.RestApiId == nil { + invalidParams.Add(request.NewErrParamRequired("RestApiId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// A list of Stage resources that are associated with the ApiKey resource. +// +// Deploying API in Stages (http://docs.aws.amazon.com/apigateway/latest/developerguide/stages.html) +type GetStagesOutput struct { + _ struct{} `type:"structure"` + + // An individual Stage resource. + Item []*Stage `locationName:"item" type:"list"` +} + +// String returns the string representation +func (s GetStagesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStagesOutput) GoString() string { + return s.String() +} + +// The GET request to get the usage data of a usage plan in a specified time +// interval. +type GetUsageInput struct { + _ struct{} `type:"structure"` + + // The ending date (e.g., 2016-12-31) of the usage data. + EndDate *string `location:"querystring" locationName:"endDate" type:"string" required:"true"` + + // The Id of the API key associated with the resultant usage data. + KeyId *string `location:"querystring" locationName:"keyId" type:"string"` + + // The maximum number of results to be returned. + Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` + + // Position + Position *string `location:"querystring" locationName:"position" type:"string"` + + // The starting date (e.g., 2016-01-01) of the usage data. + StartDate *string `location:"querystring" locationName:"startDate" type:"string" required:"true"` + + // The Id of the usage plan associated with the usage data. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetUsageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetUsageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetUsageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetUsageInput"} + if s.EndDate == nil { + invalidParams.Add(request.NewErrParamRequired("EndDate")) + } + if s.StartDate == nil { + invalidParams.Add(request.NewErrParamRequired("StartDate")) + } + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The GET request to get a usage plan of a given plan identifier. +type GetUsagePlanInput struct { + _ struct{} `type:"structure"` + + // The identifier of the UsagePlan resource to be retrieved. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetUsagePlanInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetUsagePlanInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetUsagePlanInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetUsagePlanInput"} + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The GET request to get a usage plan key of a given key identifier. +type GetUsagePlanKeyInput struct { + _ struct{} `type:"structure"` + + // The key Id of the to-be-retrieved UsagePlanKey resource representing a plan + // customer. + KeyId *string `location:"uri" locationName:"keyId" type:"string" required:"true"` + + // The Id of the UsagePlan resource representing the usage plan containing the + // to-be-retrieved UsagePlanKey resource representing a plan customer. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetUsagePlanKeyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetUsagePlanKeyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetUsagePlanKeyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetUsagePlanKeyInput"} + if s.KeyId == nil { + invalidParams.Add(request.NewErrParamRequired("KeyId")) + } + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The GET request to get all the usage plan keys representing the API keys +// added to a specified usage plan. +type GetUsagePlanKeysInput struct { + _ struct{} `type:"structure"` + + // A query parameter specifying the maximum number usage plan keys returned + // by the GET request. + Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` + + // A query parameter specifying the name of the to-be-returned usage plan keys. + NameQuery *string `location:"querystring" locationName:"name" type:"string"` + + // A query parameter specifying the zero-based index specifying the position + // of a usage plan key. + Position *string `location:"querystring" locationName:"position" type:"string"` + + // The Id of the UsagePlan resource representing the usage plan containing the + // to-be-retrieved UsagePlanKey resource representing a plan customer. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetUsagePlanKeysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetUsagePlanKeysInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetUsagePlanKeysInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetUsagePlanKeysInput"} + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Represents the collection of usage plan keys added to usage plans for the +// associated API keys and, possibly, other types of keys. +// +// Create and Use Usage Plans (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html) +type GetUsagePlanKeysOutput struct { + _ struct{} `type:"structure"` + + // Gets the current item of the usage plan keys collection. + Items []*UsagePlanKey `locationName:"item" type:"list"` + + Position *string `locationName:"position" type:"string"` +} + +// String returns the string representation +func (s GetUsagePlanKeysOutput) String() string { + return awsutil.Prettify(s) } -// The binary blob response to GetSdk, which contains the generated SDK. -type GetSdkOutput struct { - _ struct{} `type:"structure" payload:"Body"` +// GoString returns the string representation +func (s GetUsagePlanKeysOutput) GoString() string { + return s.String() +} - // The binary blob response to GetSdk, which contains the generated SDK. - Body []byte `locationName:"body" type:"blob"` +// The GET request to get all the usage plans of the caller's account. +type GetUsagePlansInput struct { + _ struct{} `type:"structure"` - // The content-disposition header value in the HTTP reseponse. - ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"` + // The identifier of the API key associated with the usage plans. + KeyId *string `location:"querystring" locationName:"keyId" type:"string"` - // The content-type header value in the HTTP response. - ContentType *string `location:"header" locationName:"Content-Type" type:"string"` + // The number of UsagePlan resources to be returned as the result. + Limit *int64 `location:"querystring" locationName:"limit" type:"integer"` + + // The zero-based array index specifying the position of the to-be-retrieved + // UsagePlan resource. + Position *string `location:"querystring" locationName:"position" type:"string"` } // String returns the string representation -func (s GetSdkOutput) String() string { +func (s GetUsagePlansInput) String() string { return awsutil.Prettify(s) } // GoString returns the string representation -func (s GetSdkOutput) GoString() string { +func (s GetUsagePlansInput) GoString() string { return s.String() } -// Requests Amazon API Gateway to get information about a Stage resource. -type GetStageInput struct { +// Represents a collection of usage plans for an AWS account. +// +// Create and Use Usage Plans (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html) +type GetUsagePlansOutput struct { _ struct{} `type:"structure"` - // The identifier of the RestApi resource for the Stage resource to get information - // about. - RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` + // Gets the current item when enumerating the collection of UsagePlan. + Items []*UsagePlan `locationName:"item" type:"list"` - // The name of the Stage resource to get information about. - StageName *string `location:"uri" locationName:"stage_name" type:"string" required:"true"` + Position *string `locationName:"position" type:"string"` } // String returns the string representation -func (s GetStageInput) String() string { +func (s GetUsagePlansOutput) String() string { return awsutil.Prettify(s) } // GoString returns the string representation -func (s GetStageInput) GoString() string { +func (s GetUsagePlansOutput) GoString() string { return s.String() } -// Validate inspects the fields of the type to determine if they are valid. -func (s *GetStageInput) Validate() error { - invalidParams := request.ErrInvalidParams{Context: "GetStageInput"} - if s.RestApiId == nil { - invalidParams.Add(request.NewErrParamRequired("RestApiId")) - } - if s.StageName == nil { - invalidParams.Add(request.NewErrParamRequired("StageName")) - } - - if invalidParams.Len() > 0 { - return invalidParams - } - return nil -} +// The POST request to import API keys from an external source, such as a CSV-formatted +// file. +type ImportApiKeysInput struct { + _ struct{} `type:"structure" payload:"Body"` -// Requests Amazon API Gateway to get information about one or more Stage resources. -type GetStagesInput struct { - _ struct{} `type:"structure"` + // The payload of the POST request to import API keys. For the payload format, + // see API Key File Format (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-key-file-format.html). + Body []byte `locationName:"body" type:"blob" required:"true"` - // The stages' deployment identifiers. - DeploymentId *string `location:"querystring" locationName:"deploymentId" type:"string"` + // A query parameter to indicate whether to rollback ApiKey importation (true) + // or not (false) when error is encountered. + FailOnWarnings *bool `location:"querystring" locationName:"failonwarnings" type:"boolean"` - // The stages' API identifiers. - RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` + // A query parameter to specify the input format to imported API keys. Currently, + // only the csv format is supported. + Format *string `location:"querystring" locationName:"format" type:"string" required:"true" enum:"ApiKeysFormat"` } // String returns the string representation -func (s GetStagesInput) String() string { +func (s ImportApiKeysInput) String() string { return awsutil.Prettify(s) } // GoString returns the string representation -func (s GetStagesInput) GoString() string { +func (s ImportApiKeysInput) GoString() string { return s.String() } // Validate inspects the fields of the type to determine if they are valid. -func (s *GetStagesInput) Validate() error { - invalidParams := request.ErrInvalidParams{Context: "GetStagesInput"} - if s.RestApiId == nil { - invalidParams.Add(request.NewErrParamRequired("RestApiId")) +func (s *ImportApiKeysInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ImportApiKeysInput"} + if s.Body == nil { + invalidParams.Add(request.NewErrParamRequired("Body")) + } + if s.Format == nil { + invalidParams.Add(request.NewErrParamRequired("Format")) } if invalidParams.Len() > 0 { @@ -6810,21 +8123,24 @@ func (s *GetStagesInput) Validate() error { return nil } -// A list of Stage resource that are associated with the ApiKey resource. -type GetStagesOutput struct { +// The identifier of an API key used to reference an API key in a usage plan. +type ImportApiKeysOutput struct { _ struct{} `type:"structure"` - // An individual Stage resource. - Item []*Stage `locationName:"item" type:"list"` + // A list of all the ApiKey identifiers. + Ids []*string `locationName:"ids" type:"list"` + + // A list of warning messages. + Warnings []*string `locationName:"warnings" type:"list"` } // String returns the string representation -func (s GetStagesOutput) String() string { +func (s ImportApiKeysOutput) String() string { return awsutil.Prettify(s) } // GoString returns the string representation -func (s GetStagesOutput) GoString() string { +func (s ImportApiKeysOutput) GoString() string { return s.String() } @@ -6868,7 +8184,10 @@ func (s *ImportRestApiInput) Validate() error { return nil } -// Represents a HTTP, AWS, or Mock integration. +// Represents an HTTP, AWS, or Mock integration. +// +// In the API Gateway console, the built-in Lambda integration is an AWS integration. +// Creating an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type Integration struct { _ struct{} `type:"structure"` @@ -6890,32 +8209,56 @@ type Integration struct { HttpMethod *string `locationName:"httpMethod" type:"string"` // Specifies the integration's responses. + // + // Example: Get integration responses of a method + // + // Request + // + // GET /restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200 + // HTTP/1.1 Content-Type: application/json Host: apigateway.us-east-1.amazonaws.com + // X-Amz-Date: 20160607T191449Z Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160607/us-east-1/apigateway/aws4_request, + // SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response + // + // The successful response returns 200 OK status and a payload as follows: + // + // { "_links": { "curies": { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-response-{rel}.html", + // "name": "integrationresponse", "templated": true }, "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200", + // "title": "200" }, "integrationresponse:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" + // }, "integrationresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" + // } }, "responseParameters": { "method.response.header.Content-Type": "'application/xml'" + // }, "responseTemplates": { "application/json": "$util.urlDecode(\"%3CkinesisStreams%3E#foreach($stream + // in $input.path('$.StreamNames'))%3Cstream%3E%3Cname%3E$stream%3C/name%3E%3C/stream%3E#end%3C/kinesisStreams%3E\")\n" + // }, "statusCode": "200" } Creating an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) IntegrationResponses map[string]*IntegrationResponse `locationName:"integrationResponses" type:"map"` - // Specifies the pass-through behavior for incoming requests based on the Content-Type - // header in the request, and the available requestTemplates defined on the - // Integration. There are three valid values: WHEN_NO_MATCH, WHEN_NO_TEMPLATES, + // Specifies how the method request body of an unmapped content type will be + // passed through the integration request to the back end without transformation. + // A content type is unmapped if no mapping template is defined in the integration + // or the content type does not match any of the mapped content types, as specified + // in requestTemplates. There are three valid values: WHEN_NO_MATCH, WHEN_NO_TEMPLATES, // and NEVER. // - // WHEN_NO_MATCH passes the request body for unmapped content types through - // to the Integration backend without transformation. - // - // NEVER rejects unmapped content types with an HTTP 415 'Unsupported Media - // Type' response. - // - // WHEN_NO_TEMPLATES will allow pass-through when the Integration has NO content - // types mapped to templates. However if there is at least one content type - // defined, unmapped content types will be rejected with the same 415 response. + // WHEN_NO_MATCH passes the method request body through the integration request + // to the back end without transformation when the method request content type + // does not match any content type associated with the mapping templates defined + // in the integration request. WHEN_NO_TEMPLATES passes the method request + // body through the integration request to the back end without transformation + // when no mapping template is defined in the integration request. If a template + // is defined when this option is selected, the method request of an unmapped + // content-type will be rejected with an HTTP 415 Unsupported Media Type response. + // NEVER rejects the method request with an HTTP 415 Unsupported Media Type + // response when either the method request content type does not match any content + // type associated with the mapping templates defined in the integration request + // or no mapping template is defined in the integration request. PassthroughBehavior *string `locationName:"passthroughBehavior" type:"string"` - // Represents requests parameters that are sent with the backend request. Request - // parameters are represented as a key/value map, with a destination as the - // key and a source as the value. A source must match an existing method request - // parameter, or a static value. Static values must be enclosed with single - // quotes, and be pre-encoded based on their destination in the request. The - // destination must match the pattern integration.request.{location}.{name}, - // where location is either querystring, path, or header. name must be a valid, - // unique parameter name. + // A key-value map specifying request parameters that are passed from the method + // request to the back end. The key is an integration request parameter name + // and the associated value is a method request parameter value or static value + // that must be enclosed within single quotes and pre-encoded as required by + // the back end. The method request parameter value must match the pattern of + // method.request.{location}.{name}, where location is querystring, path, or + // header and name must be a valid and unique method request parameter name. RequestParameters map[string]*string `locationName:"requestParameters" type:"map"` // Represents a map of Velocity templates that are applied on the request payload @@ -6951,17 +8294,22 @@ func (s Integration) GoString() string { // Represents an integration response. The status code must map to an existing // MethodResponse, and parameters and templates can be used to transform the -// backend response. +// back-end response. +// +// Creating an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type IntegrationResponse struct { _ struct{} `type:"structure"` - // Represents response parameters that can be read from the backend response. - // Response parameters are represented as a key/value map, with a destination - // as the key and a source as the value. A destination must match an existing - // response parameter in the MethodResponse. The source can be a header from - // the backend response, or a static value. Static values are specified using - // enclosing single quotes, and backend response headers can be read using the - // pattern integration.response.header.{name}. + // A key-value map specifying response parameters that are passed to the method + // response from the back end. The key is a method response header parameter + // name and the mapped value is an integration response header value, a static + // value enclosed within a pair of single quotes, or a JSON expression from + // the integration response body. The mapping key must match the pattern of + // method.response.header.{name}, where name is a valid and unique header name. + // The mapped non-static value must match the pattern of integration.response.header.{name} + // or integration.response.body.{JSON-expression}, where name is a valid and + // unique response header name and JSON-expression is a valid JSON expression + // without the $ prefix. ResponseParameters map[string]*string `locationName:"responseParameters" type:"map"` // Specifies the templates used to transform the integration response body. @@ -6970,9 +8318,13 @@ type IntegrationResponse struct { ResponseTemplates map[string]*string `locationName:"responseTemplates" type:"map"` // Specifies the regular expression (regex) pattern used to choose an integration - // response based on the response from the backend. If the backend is an AWS - // Lambda function, the AWS Lambda function error header is matched. For all - // other HTTP and AWS backends, the HTTP status code is matched. + // response based on the response from the back end. For example, if the success + // response returns nothing and the error response returns some string, you + // could use the .+ regex to match error response. However, make sure that the + // error response does not contain any newline (\n) character in such cases. + // If the back end is an AWS Lambda function, the AWS Lambda function error + // header is matched. For all other HTTP and AWS back ends, the HTTP status + // code is matched. SelectionPattern *string `locationName:"selectionPattern" type:"string"` // Specifies the status code that is used to map the integration response to @@ -6990,44 +8342,175 @@ func (s IntegrationResponse) GoString() string { return s.String() } -// Represents a method. +// Represents a client-facing interface by which the client calls the API to +// access back-end resources. A Method resource is integrated with an Integration +// resource. Both consist of a request and one or more responses. The method +// request takes the client input that is passed to the back end through the +// integration request. A method response returns the output from the back end +// to the client through an integration response. A method request is embodied +// in a Method resource, whereas an integration request is embodied in an Integration +// resource. On the other hand, a method response is represented by a MethodResponse +// resource, whereas an integration response is represented by an IntegrationResponse +// resource. +// +// Example: Retrive the GET method on a specified resource +// +// Request +// +// The following example request retrieves the information about the GET method +// on an API resource (3kzxbg5sa2) of an API (fugvjdxtri). +// +// GET /restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET HTTP/1.1 Content-Type: +// application/json Host: apigateway.us-east-1.amazonaws.com X-Amz-Date: 20160603T210259Z +// Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160603/us-east-1/apigateway/aws4_request, +// SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response +// +// The successful response returns a 200 OK status code and a payload similar +// to the following: +// +// { "_links": { "curies": [ { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-{rel}.html", +// "name": "integration", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-response-{rel}.html", +// "name": "integrationresponse", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-{rel}.html", +// "name": "method", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-response-{rel}.html", +// "name": "methodresponse", "templated": true } ], "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET", +// "name": "GET", "title": "GET" }, "integration:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" +// }, "method:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET" +// }, "method:integration": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" +// }, "method:responses": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200", +// "name": "200", "title": "200" }, "method:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET" +// }, "methodresponse:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/{status_code}", +// "templated": true } }, "apiKeyRequired": true, "authorizationType": "NONE", +// "httpMethod": "GET", "_embedded": { "method:integration": { "_links": { "self": +// { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" +// }, "integration:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" +// }, "integration:responses": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200", +// "name": "200", "title": "200" }, "integration:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" +// }, "integrationresponse:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/{status_code}", +// "templated": true } }, "cacheKeyParameters": [], "cacheNamespace": "3kzxbg5sa2", +// "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", "httpMethod": +// "POST", "passthroughBehavior": "WHEN_NO_MATCH", "requestParameters": { "integration.request.header.Content-Type": +// "'application/x-amz-json-1.1'" }, "requestTemplates": { "application/json": +// "{\n}" }, "type": "AWS", "uri": "arn:aws:apigateway:us-east-1:kinesis:action/ListStreams", +// "_embedded": { "integration:responses": { "_links": { "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200", +// "name": "200", "title": "200" }, "integrationresponse:delete": { "href": +// "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" +// }, "integrationresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" +// } }, "responseParameters": { "method.response.header.Content-Type": "'application/xml'" +// }, "responseTemplates": { "application/json": "$util.urlDecode(\"%3CkinesisStreams%3E%23foreach(%24stream%20in%20%24input.path(%27%24.StreamNames%27))%3Cstream%3E%3Cname%3E%24stream%3C%2Fname%3E%3C%2Fstream%3E%23end%3C%2FkinesisStreams%3E\")" +// }, "statusCode": "200" } } }, "method:responses": { "_links": { "self": { +// "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200", +// "name": "200", "title": "200" }, "methodresponse:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" +// }, "methodresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" +// } }, "responseModels": { "application/json": "Empty" }, "responseParameters": +// { "method.response.header.Content-Type": false }, "statusCode": "200" } } +// } In the example above, the response template for the 200 OK response maps +// the JSON output from the ListStreams action in the back end to an XML output. +// The mapping template is URL-encoded as %3CkinesisStreams%3E%23foreach(%24stream%20in%20%24input.path(%27%24.StreamNames%27))%3Cstream%3E%3Cname%3E%24stream%3C%2Fname%3E%3C%2Fstream%3E%23end%3C%2FkinesisStreams%3E +// and the output is decoded using the $util.urlDecode() (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#util-templat-reference) +// helper function. +// +// MethodResponse, Integration, IntegrationResponse, Resource, Set up an +// API's method (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-method-settings.html) type Method struct { _ struct{} `type:"structure"` - // Specifies whether the method requires a valid ApiKey. + // A boolean flag specifying whether a valid ApiKey is required to invoke this + // method. ApiKeyRequired *bool `locationName:"apiKeyRequired" type:"boolean"` // The method's authorization type. AuthorizationType *string `locationName:"authorizationType" type:"string"` - // Specifies the identifier of an Authorizer to use on this Method. The authorizationType + // The identifier of an Authorizer to use on this method. The authorizationType // must be CUSTOM. AuthorizerId *string `locationName:"authorizerId" type:"string"` - // The HTTP method. + // The method's HTTP verb. HttpMethod *string `locationName:"httpMethod" type:"string"` - // The method's integration. + // Gets the method's integration responsible for passing the client-submitted + // request to the back end and performing necessary transformations to make + // the request compliant with the back end. + // + // Example: + // + // Request + // + // GET /restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration HTTP/1.1 + // Content-Type: application/json Host: apigateway.us-east-1.amazonaws.com Content-Length: + // 117 X-Amz-Date: 20160613T213210Z Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160613/us-east-1/apigateway/aws4_request, + // SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response + // + // The successful response returns a 200 OK status code and a payload similar + // to the following: + // + // { "_links": { "curies": [ { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-{rel}.html", + // "name": "integration", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-response-{rel}.html", + // "name": "integrationresponse", "templated": true } ], "self": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration" + // }, "integration:delete": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration" + // }, "integration:responses": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration/responses/200", + // "name": "200", "title": "200" }, "integration:update": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration" + // }, "integrationresponse:put": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration/responses/{status_code}", + // "templated": true } }, "cacheKeyParameters": [], "cacheNamespace": "0cjtch", + // "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", "httpMethod": + // "POST", "passthroughBehavior": "WHEN_NO_MATCH", "requestTemplates": { "application/json": + // "{\n \"a\": \"$input.params('operand1')\",\n \"b\": \"$input.params('operand2')\", + // \n \"op\": \"$input.params('operator')\" \n}" }, "type": "AWS", "uri": "arn:aws:apigateway:us-west-2:lambda:path//2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations", + // "_embedded": { "integration:responses": { "_links": { "self": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration/responses/200", + // "name": "200", "title": "200" }, "integrationresponse:delete": { "href": + // "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration/responses/200" + // }, "integrationresponse:update": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/integration/responses/200" + // } }, "responseParameters": { "method.response.header.operator": "integration.response.body.op", + // "method.response.header.operand_2": "integration.response.body.b", "method.response.header.operand_1": + // "integration.response.body.a" }, "responseTemplates": { "application/json": + // "#set($res = $input.path('$'))\n{\n \"result\": \"$res.a, $res.b, $res.op + // => $res.c\",\n \"a\" : \"$res.a\",\n \"b\" : \"$res.b\",\n \"op\" : \"$res.op\",\n + // \"c\" : \"$res.c\"\n}" }, "selectionPattern": "", "statusCode": "200" } } + // } AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-integration.html) MethodIntegration *Integration `locationName:"methodIntegration" type:"structure"` - // Represents available responses that can be sent to the caller. Method responses - // are represented as a key/value map, with an HTTP status code as the key and - // a MethodResponse as the value. The status codes are available for the Integration - // responses to map to. + // Gets a method response associated with a given HTTP status code. + // + // The collection of method responses are encapsulated in a key-value map, + // where the key is a response's HTTP status code and the value is a MethodResponse + // resource that specifies the response returned to the caller from the back + // end through the integration response. + // + // Example: Get a 200 OK response of a GET method + // + // Request + // + // GET /restapis/uojnr9hd57/resources/0cjtch/methods/GET/responses/200 HTTP/1.1 + // Content-Type: application/json Host: apigateway.us-east-1.amazonaws.com Content-Length: + // 117 X-Amz-Date: 20160613T215008Z Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160613/us-east-1/apigateway/aws4_request, + // SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response + // + // The successful response returns a 200 OK status code and a payload similar + // to the following: + // + // { "_links": { "curies": { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-response-{rel}.html", + // "name": "methodresponse", "templated": true }, "self": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/responses/200", + // "title": "200" }, "methodresponse:delete": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/responses/200" + // }, "methodresponse:update": { "href": "/restapis/uojnr9hd57/resources/0cjtch/methods/GET/responses/200" + // } }, "responseModels": { "application/json": "Empty" }, "responseParameters": + // { "method.response.header.operator": false, "method.response.header.operand_2": + // false, "method.response.header.operand_1": false }, "statusCode": "200" } + // AWS CLI (http://docs.aws.amazon.com/cli/latest/reference/apigateway/get-method-response.html) MethodResponses map[string]*MethodResponse `locationName:"methodResponses" type:"map"` - // Specifies the Model resources used for the request's content type. Request - // models are represented as a key/value map, with a content type as the key - // and a Model name as the value. + // A key-value map specifying data schemas, represented by Model resources, + // (as the mapped value) of the request payloads of given content types (as + // the mapping key). RequestModels map[string]*string `locationName:"requestModels" type:"map"` - // Represents request parameters that can be accepted by Amazon API Gateway. - // Request parameters are represented as a key/value map, with a source as the - // key and a Boolean flag as the value. The Boolean flag is used to specify - // whether the parameter is required. A source must match the pattern method.request.{location}.{name}, - // where location is either querystring, path, or header. name is a valid, unique - // parameter name. Sources specified here are available to the integration for - // mapping to integration request parameters or templates. + // A key-value map defining required or optional method request parameters that + // can be accepted by Amazon API Gateway. A key is a method request parameter + // name matching the pattern of method.request.{location}.{name}, where location + // is querystring, path, or header and name is a valid and unique parameter + // name. The value associated with the key is a Boolean flag indicating whether + // the parameter is required (true) or optional (false). The method request + // parameter names defined here are available in Integration to be mapped to + // integration request parameters or templates. RequestParameters map[string]*bool `locationName:"requestParameters" type:"map"` } @@ -7041,9 +8524,30 @@ func (s Method) GoString() string { return s.String() } -// Represents a method response. Amazon API Gateway sends back the status code -// to the caller as the HTTP status code. Parameters and models can be used -// to transform the response from the method's integration. +// Represents a method response of a given HTTP status code returned to the +// client. The method response is passed from the back end through the associated +// integration response that can be transformed using a mapping template. +// +// Example: A MethodResponse instance of an API +// +// Request +// +// The example request retrieves a MethodResponse of the 200 status code. +// +// GET /restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200 +// HTTP/1.1 Content-Type: application/json Host: apigateway.us-east-1.amazonaws.com +// X-Amz-Date: 20160603T222952Z Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160603/us-east-1/apigateway/aws4_request, +// SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response +// +// The successful response returns 200 OK status and a payload as follows: +// +// { "_links": { "curies": { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-response-{rel}.html", +// "name": "methodresponse", "templated": true }, "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200", +// "title": "200" }, "methodresponse:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" +// }, "methodresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" +// } }, "responseModels": { "application/json": "Empty" }, "responseParameters": +// { "method.response.header.Content-Type": false }, "statusCode": "200" } +// Method, IntegrationResponse, Integration Creating an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type MethodResponse struct { _ struct{} `type:"structure"` @@ -7052,13 +8556,18 @@ type MethodResponse struct { // and a Model name as the value. ResponseModels map[string]*string `locationName:"responseModels" type:"map"` - // Represents response parameters that can be sent back to the caller by Amazon - // API Gateway. Response parameters are represented as a key/value map, with - // a destination as the key and a boolean flag as the value, which is used to - // specify whether the parameter is required. A destination must match the pattern - // method.response.header.{name}, where name is a valid, unique header name. - // Destinations specified here are available to the integration for mapping - // from integration response parameters. + // A key-value map specifying required or optional response parameters that + // Amazon API Gateway can send back to the caller. A key defines a method response + // header and the value specifies whether the associated method response header + // is required or not. The expression of the key must match the pattern method.response.header.{name}, + // where name is a valid and unique header name. Amazon API Gateway passes certain + // integration response data to the method response headers specified here according + // to the mapping you prescribe in the API's IntegrationResponse. The integration + // response data that can be mapped include an integration response header expressed + // in integration.response.header.{name}, a static value enclosed within a pair + // of single quotes (e.g., 'application/json'), or a JSON expression from the + // back-end response payload in the form of integration.response.body.{JSON-expression}, + // where JSON-expression is a valid JSON expression without the $ prefix.) ResponseParameters map[string]*bool `locationName:"responseParameters" type:"map"` // The method response's status code. @@ -7084,8 +8593,8 @@ type MethodSetting struct { // is a Boolean. CacheDataEncrypted *bool `locationName:"cacheDataEncrypted" type:"boolean"` - // Specifies the time to live (TTL) in seconds, for cached responses. The higher - // a the TTL, the longer the response will be cached. The PATCH path for this + // Specifies the time to live (TTL), in seconds, for cached responses. The higher + // the TTL, the longer the response will be cached. The PATCH path for this // setting is /{method_setting_key}/caching/ttlInSeconds, and the value is an // integer. CacheTtlInSeconds *int64 `locationName:"cacheTtlInSeconds" type:"integer"` @@ -7096,10 +8605,9 @@ type MethodSetting struct { // the value is a Boolean. CachingEnabled *bool `locationName:"cachingEnabled" type:"boolean"` - // Specifies the whether data trace logging is enabled for this method, which - // effects the log entries pushed to Amazon CloudWatch Logs. The PATCH path - // for this setting is /{method_setting_key}/logging/dataTrace, and the value - // is a Boolean. + // Specifies whether data trace logging is enabled for this method, which effects + // the log entries pushed to Amazon CloudWatch Logs. The PATCH path for this + // setting is /{method_setting_key}/logging/dataTrace, and the value is a Boolean. DataTraceEnabled *bool `locationName:"dataTraceEnabled" type:"boolean"` // Specifies the logging level for this method, which effects the log entries @@ -7125,8 +8633,8 @@ type MethodSetting struct { // and the value is a double. ThrottlingRateLimit *float64 `locationName:"throttlingRateLimit" type:"double"` - // Specifies the strategy on how to handle the unauthorized requests for cache - // invalidation. The PATCH path for this setting is /{method_setting_key}/caching/unauthorizedCacheControlHeaderStrategy, + // Specifies how to handle unauthorized requests for cache invalidation. The + // PATCH path for this setting is /{method_setting_key}/caching/unauthorizedCacheControlHeaderStrategy, // and the available values are FAIL_WITH_403, SUCCEED_WITH_RESPONSE_HEADER, // SUCCEED_WITHOUT_RESPONSE_HEADER. UnauthorizedCacheControlHeaderStrategy *string `locationName:"unauthorizedCacheControlHeaderStrategy" type:"string" enum:"UnauthorizedCacheControlHeaderStrategy"` @@ -7163,7 +8671,17 @@ func (s MethodSnapshot) GoString() string { return s.String() } -// Represents the structure of a request or response payload for a method. +// Represents the data structure of a method's request or response payload. +// +// A request model defines the data structure of the client-supplied request +// payload. A response model defines the data structure of the response payload +// returned by the back end. Although not required, models are useful for mapping +// payloads between the front end and back end. +// +// A model is used for generating an API's SDK, validating the input request +// body, and creating a skeletal mapping template. +// +// Method, MethodResponse, Models and Mappings (http://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html) type Model struct { _ struct{} `type:"structure"` @@ -7181,6 +8699,10 @@ type Model struct { // The schema for the model. For application/json models, this should be JSON-schema // draft v4 (http://json-schema.org/documentation.html" target="_blank) model. + // Do not include "\*/" characters in the description of any properties because + // such "\*/" characters may be interpreted as the closing marker for comments + // in some languages, such as Java or JavaScript, causing the installation of + // your API's SDK generated by API Gateway to fail. Schema *string `locationName:"schema" type:"string"` } @@ -7200,23 +8722,27 @@ func (s Model) GoString() string { type PatchOperation struct { _ struct{} `type:"structure"` - // The "move" and "copy" operation object MUST contain a "from" member, which - // is a string containing a JSON Pointer value that references the location - // in the target document to move the value from. + // Not supported. From *string `locationName:"from" type:"string"` - // A patch operation whose value indicates the operation to perform. Its value - // MUST be one of "add", "remove", "replace", "move", "copy", or "test"; other - // values are errors. + // An update operation to be performed with this PATCH request. The valid value + // can be "add", "remove", or "replace". Not all valid operations are supported + // for a given resource. Support of the operations depends on specific operational + // contexts. Attempts to apply an unsupported operation on a resource will return + // an error message. Op *string `locationName:"op" type:"string" enum:"op"` - // Operation objects MUST have exactly one "path" member. That member's value - // is a string containing a `JSON-Pointer` value that references a location - // within the target document (the "target location") where the operation is - // performed. + // The op operation's target, as identified by a JSON Pointer (https://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-08) + // value that references a location within the targeted resource. For example, + // if the target resource has an updateable property of {"name":"value"}, the + // path for this property is /name. If the name property value is a JSON object + // (e.g., {"name": {"child/name": "child-value"}}), the path for the child/name + // property will be /name/child~1name. Any slash ("/") character appearing in + // path names must be escaped with "~1", as shown in the example above. Each + // op operation can have only one path associated with it. Path *string `locationName:"path" type:"string"` - // The actual value content. + // The new target value of the update operation. Value *string `locationName:"value" type:"string"` } @@ -7251,29 +8777,28 @@ type PutIntegrationInput struct { IntegrationHttpMethod *string `locationName:"httpMethod" type:"string"` // Specifies the pass-through behavior for incoming requests based on the Content-Type - // header in the request, and the available requestTemplates defined on the - // Integration. There are three valid values: WHEN_NO_MATCH, WHEN_NO_TEMPLATES, - // and NEVER. + // header in the request, and the available mapping templates specified as the + // requestTemplates property on the Integration resource. There are three valid + // values: WHEN_NO_MATCH, WHEN_NO_TEMPLATES, and NEVER. // // WHEN_NO_MATCH passes the request body for unmapped content types through - // to the Integration backend without transformation. + // to the integration back end without transformation. // // NEVER rejects unmapped content types with an HTTP 415 'Unsupported Media // Type' response. // - // WHEN_NO_TEMPLATES will allow pass-through when the Integration has NO content + // WHEN_NO_TEMPLATES allows pass-through when the integration has NO content // types mapped to templates. However if there is at least one content type // defined, unmapped content types will be rejected with the same 415 response. PassthroughBehavior *string `locationName:"passthroughBehavior" type:"string"` - // Represents request parameters that are sent with the backend request. Request - // parameters are represented as a key/value map, with a destination as the - // key and a source as the value. A source must match an existing method request - // parameter, or a static value. Static values must be enclosed with single - // quotes, and be pre-encoded based on their destination in the request. The - // destination must match the pattern integration.request.{location}.{name}, - // where location is either querystring, path, or header. name must be a valid, - // unique parameter name. + // A key-value map specifying request parameters that are passed from the method + // request to the back end. The key is an integration request parameter name + // and the associated value is a method request parameter value or static value + // that must be enclosed within single quotes and pre-encoded as required by + // the back end. The method request parameter value must match the pattern of + // method.request.{location}.{name}, where location is querystring, path, or + // header and name must be a valid and unique method request parameter name. RequestParameters map[string]*string `locationName:"requestParameters" type:"map"` // Represents a map of Velocity templates that are applied on the request payload @@ -7340,13 +8865,16 @@ type PutIntegrationResponseInput struct { // Specifies a put integration response request's resource identifier. ResourceId *string `location:"uri" locationName:"resource_id" type:"string" required:"true"` - // Represents response parameters that can be read from the backend response. - // Response parameters are represented as a key/value map, with a destination - // as the key and a source as the value. A destination must match an existing - // response parameter in the Method. The source can be a header from the backend - // response, or a static value. Static values are specified using enclosing - // single quotes, and backend response headers can be read using the pattern - // integration.response.header.{name}. + // A key-value map specifying response parameters that are passed to the method + // response from the back end. The key is a method response header parameter + // name and the mapped value is an integration response header value, a static + // value enclosed within a pair of single quotes, or a JSON expression from + // the integration response body. The mapping key must match the pattern of + // method.response.header.{name}, where name is a valid and unique header name. + // The mapped non-static value must match the pattern of integration.response.header.{name} + // or integration.response.body.{JSON-expression}, where name must be a valid + // and unique response header name and JSON-expression a valid JSON expression + // without the $ prefix. ResponseParameters map[string]*string `locationName:"responseParameters" type:"map"` // Specifies a put integration response's templates. @@ -7409,7 +8937,7 @@ type PutMethodInput struct { // is CUSTOM. AuthorizerId *string `locationName:"authorizerId" type:"string"` - // Specifies the put method request's HTTP method type. + // Specifies the method request's HTTP method type. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // Specifies the Model resources used for the request's content type. Request @@ -7417,14 +8945,14 @@ type PutMethodInput struct { // and a Model name as the value. RequestModels map[string]*string `locationName:"requestModels" type:"map"` - // Represents requests parameters that are sent with the backend request. Request - // parameters are represented as a key/value map, with a destination as the - // key and a source as the value. A source must match an existing method request - // parameter, or a static value. Static values must be enclosed with single - // quotes, and be pre-encoded based on their destination in the request. The - // destination must match the pattern integration.request.{location}.{name}, - // where location is either querystring, path, or header. name must be a valid, - // unique parameter name. + // A key-value map defining required or optional method request parameters that + // can be accepted by Amazon API Gateway. A key defines a method request parameter + // name matching the pattern of method.request.{location}.{name}, where location + // is querystring, path, or header and name is a valid and unique parameter + // name. The value associated with the key is a Boolean flag indicating whether + // the parameter is required (true) or optional (false). The method request + // parameter names defined here are available in Integration to be mapped to + // integration request parameters or body-mapping templates. RequestParameters map[string]*bool `locationName:"requestParameters" type:"map"` // The Resource identifier for the new Method resource. @@ -7470,7 +8998,7 @@ func (s *PutMethodInput) Validate() error { type PutMethodResponseInput struct { _ struct{} `type:"structure"` - // The HTTP verb that identifies the Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` // The Resource identifier for the Method resource. @@ -7481,13 +9009,17 @@ type PutMethodResponseInput struct { // and a Model name as the value. ResponseModels map[string]*string `locationName:"responseModels" type:"map"` - // Represents response parameters that can be sent back to the caller by Amazon - // API Gateway. Response parameters are represented as a key/value map, with - // a destination as the key and a Boolean flag as the value. The Boolean flag - // is used to specify whether the parameter is required. A destination must - // match the pattern method.response.header.{name}, where name is a valid, unique - // header name. Destinations specified here are available to the integration - // for mapping from integration response parameters. + // A key-value map specifying required or optional response parameters that + // Amazon API Gateway can send back to the caller. A key defines a method response + // header name and the associated value is a Boolean flag indicating whether + // the method response parameter is required or not. The method response header + // names must match the pattern of method.response.header.{name}, where name + // is a valid and unique header name. The response parameter names defined here + // are available in the integration response to be mapped from an integration + // response header expressed in integration.response.header.{name}, a static + // value enclosed within a pair of single quotes (e.g., 'application/json'), + // or a JSON expression from the back-end response payload in the form of integration.response.body.{JSON-expression}, + // where JSON-expression is a valid JSON expression without the $ prefix.) ResponseParameters map[string]*bool `locationName:"responseParameters" type:"map"` // The RestApi identifier for the Method resource. @@ -7579,7 +9111,35 @@ func (s *PutRestApiInput) Validate() error { return nil } -// Represents a resource. +// Quotas configured for a usage plan. +type QuotaSettings struct { + _ struct{} `type:"structure"` + + // The maximum number of requests that can be made in a given time period. + Limit *int64 `locationName:"limit" type:"integer"` + + // The number of requests subtracted from the given limit in the initial time + // period. + Offset *int64 `locationName:"offset" type:"integer"` + + // The time period in which the limit applies. Valid values are "DAY", "WEEK" + // or "MONTH". + Period *string `locationName:"period" type:"string" enum:"QuotaPeriodType"` +} + +// String returns the string representation +func (s QuotaSettings) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s QuotaSettings) GoString() string { + return s.String() +} + +// Represents an API resource. +// +// Create an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type Resource struct { _ struct{} `type:"structure"` @@ -7595,8 +9155,61 @@ type Resource struct { // The last path segment for this resource. PathPart *string `locationName:"pathPart" type:"string"` - // Map of methods for this resource, which is included only if the request uses - // the embed query option. + // Gets an API resource's method of a given HTTP verb. + // + // The resource methods are a map of methods indexed by methods' HTTP verbs + // enabled on the resource. This method map is included in the 200 OK response + // of the GET /restapis/{restapi_id}/resources/{resource_id} or GET /restapis/{restapi_id}/resources/{resource_id}?embed=methods + // request. + // + // Example: Get the GET method of an API resource + // + // Request + // + // GET /restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET HTTP/1.1 Content-Type: + // application/json Host: apigateway.us-east-1.amazonaws.com X-Amz-Date: 20160608T031827Z + // Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160608/us-east-1/apigateway/aws4_request, + // SignedHeaders=content-type;host;x-amz-date, Signature={sig4_hash} Response + // + // { "_links": { "curies": [ { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-{rel}.html", + // "name": "integration", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-integration-response-{rel}.html", + // "name": "integrationresponse", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-{rel}.html", + // "name": "method", "templated": true }, { "href": "http://docs.aws.amazon.com/apigateway/latest/developerguide/restapi-method-response-{rel}.html", + // "name": "methodresponse", "templated": true } ], "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET", + // "name": "GET", "title": "GET" }, "integration:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" + // }, "method:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET" + // }, "method:integration": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" + // }, "method:responses": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200", + // "name": "200", "title": "200" }, "method:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET" + // }, "methodresponse:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/{status_code}", + // "templated": true } }, "apiKeyRequired": false, "authorizationType": "NONE", + // "httpMethod": "GET", "_embedded": { "method:integration": { "_links": { "self": + // { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" + // }, "integration:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" + // }, "integration:responses": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200", + // "name": "200", "title": "200" }, "integration:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration" + // }, "integrationresponse:put": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/{status_code}", + // "templated": true } }, "cacheKeyParameters": [], "cacheNamespace": "3kzxbg5sa2", + // "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", "httpMethod": + // "POST", "passthroughBehavior": "WHEN_NO_MATCH", "requestParameters": { "integration.request.header.Content-Type": + // "'application/x-amz-json-1.1'" }, "requestTemplates": { "application/json": + // "{\n}" }, "type": "AWS", "uri": "arn:aws:apigateway:us-east-1:kinesis:action/ListStreams", + // "_embedded": { "integration:responses": { "_links": { "self": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200", + // "name": "200", "title": "200" }, "integrationresponse:delete": { "href": + // "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" + // }, "integrationresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/integration/responses/200" + // } }, "responseParameters": { "method.response.header.Content-Type": "'application/xml'" + // }, "responseTemplates": { "application/json": "$util.urlDecode(\"%3CkinesisStreams%3E#foreach($stream + // in $input.path('$.StreamNames'))%3Cstream%3E%3Cname%3E$stream%3C/name%3E%3C/stream%3E#end%3C/kinesisStreams%3E\")\n" + // }, "statusCode": "200" } } }, "method:responses": { "_links": { "self": { + // "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200", + // "name": "200", "title": "200" }, "methodresponse:delete": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" + // }, "methodresponse:update": { "href": "/restapis/fugvjdxtri/resources/3kzxbg5sa2/methods/GET/responses/200" + // } }, "responseModels": { "application/json": "Empty" }, "responseParameters": + // { "method.response.header.Content-Type": false }, "statusCode": "200" } } + // } If the OPTIONS is enabled on the resource, you can follow the example here + // to get that method. Just replace the GET of the last path segment in the + // request URL with OPTIONS. ResourceMethods map[string]*Method `locationName:"resourceMethods" type:"map"` } @@ -7611,6 +9224,8 @@ func (s Resource) GoString() string { } // Represents a REST API. +// +// Create an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html) type RestApi struct { _ struct{} `type:"structure"` @@ -7628,6 +9243,8 @@ type RestApi struct { // The API's name. Name *string `locationName:"name" type:"string"` + // The warning messages reported when failonwarnings is turned on during API + // import. Warnings []*string `locationName:"warnings" type:"list"` } @@ -7643,6 +9260,8 @@ func (s RestApi) GoString() string { // Represents a unique identifier for a version of a deployed RestApi that is // callable by users. +// +// Deploy an API (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html) type Stage struct { _ struct{} `type:"structure"` @@ -7655,6 +9274,7 @@ type Stage struct { // The status of the cache cluster for the stage, if enabled. CacheClusterStatus *string `locationName:"cacheClusterStatus" type:"string" enum:"CacheClusterStatus"` + // The identifier of a client certificate for an API stage. ClientCertificateId *string `locationName:"clientCertificateId" type:"string"` // The date and time that the stage was created, in ISO 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" @@ -7671,9 +9291,11 @@ type Stage struct { // 8601 format (http://www.iso.org/iso/home/standards/iso8601.htm" target="_blank). LastUpdatedDate *time.Time `locationName:"lastUpdatedDate" type:"timestamp" timestampFormat:"unix"` - // A map that defines the method settings for a Stage resource. Keys are defined - // as {resource_path}/{http_method} for an individual method override, or \*/\* - // for the settings applied to all methods in the stage. + // A map that defines the method settings for a Stage resource. Keys (designated + // as /{method_setting_key below) are method paths defined as {resource_path}/{http_method} + // for an individual method override, or /\*/\* for overriding all methods in + // the stage. Any forward slash ("/") characters in the resource_path part must + // be encoded as "~1" as in, for example, ~1resource~1sub-resource/GET. MethodSettings map[string]*MethodSetting `locationName:"methodSettings" type:"map"` // The name of the stage is the first path segment in the Uniform Resource Identifier @@ -7681,7 +9303,8 @@ type Stage struct { StageName *string `locationName:"stageName" type:"string"` // A map that defines the stage variables for a Stage resource. Variable names - // can have alphanumeric characters, and the values must match [A-Za-z0-9-._~:/?#&=,]+. + // can have alphanumeric and underscore characters, and the values must match + // [A-Za-z0-9-._~:/?#&=,]+. Variables map[string]*string `locationName:"variables" type:"map"` } @@ -7772,25 +9395,28 @@ func (s *TestInvokeAuthorizerInput) Validate() error { return nil } -// Represents the response of the test invoke request in for a custom Authorizer +// Represents the response of the test invoke request for a custom Authorizer type TestInvokeAuthorizerOutput struct { _ struct{} `type:"structure"` Authorization map[string][]*string `locationName:"authorization" type:"map"` + // The open identity claims (http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims), + // with any supported custom attributes, returned from the Cognito Your User + // Pool configured for the API. Claims map[string]*string `locationName:"claims" type:"map"` // The HTTP status code that the client would have received. Value is 0 if the // authorizer succeeded. ClientStatus *int64 `locationName:"clientStatus" type:"integer"` - // The execution latency of the test authorizer request + // The execution latency of the test authorizer request. Latency *int64 `locationName:"latency" type:"long"` // The Amazon API Gateway execution log for the test authorizer request. Log *string `locationName:"log" type:"string"` - // The policy JSON document returned by the Authorizer + // The JSON policy document returned by the Authorizer Policy *string `locationName:"policy" type:"string"` // The principal identity returned by the Authorizer @@ -7815,8 +9441,8 @@ type TestInvokeMethodInput struct { Body *string `locationName:"body" type:"string"` // A ClientCertificate identifier to use in the test invocation. API Gateway - // will use use the certificate when making the HTTPS request to the defined - // backend endpoint. + // will use the certificate when making the HTTPS request to the defined back-end + // endpoint. ClientCertificateId *string `locationName:"clientCertificateId" type:"string"` // A key-value map of headers to simulate an incoming invocation request. @@ -7869,14 +9495,16 @@ func (s *TestInvokeMethodInput) Validate() error { return nil } -// Represents the response of the test invoke request in HTTP method. +// Represents the response of the test invoke request in the HTTP method. +// +// Test API using the API Gateway console (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-test-method.html#how-to-test-method-console) type TestInvokeMethodOutput struct { _ struct{} `type:"structure"` - // The body of HTTP response. + // The body of the HTTP response. Body *string `locationName:"body" type:"string"` - // The headers of HTTP response. + // The headers of the HTTP response. Headers map[string]*string `locationName:"headers" type:"map"` // The execution latency of the test invoke request. @@ -7899,14 +9527,16 @@ func (s TestInvokeMethodOutput) GoString() string { return s.String() } -// Returns the throttle settings. +// The API request rate limits. type ThrottleSettings struct { _ struct{} `type:"structure"` - // Returns the burstLimit when ThrottleSettings is called. + // The API request burst limit, the maximum rate limit over a time ranging from + // one to a few seconds, depending upon whether the underlying token bucket + // is at its full capacity. BurstLimit *int64 `locationName:"burstLimit" type:"integer"` - // Returns the rateLimit when ThrottleSettings is called. + // The API request steady-state rate limit. RateLimit *float64 `locationName:"rateLimit" type:"double"` } @@ -7925,8 +9555,8 @@ func (s ThrottleSettings) GoString() string { type UpdateAccountInput struct { _ struct{} `type:"structure"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` } @@ -7947,8 +9577,8 @@ type UpdateApiKeyInput struct { // The identifier of the ApiKey resource to be updated. ApiKey *string `location:"uri" locationName:"api_Key" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` } @@ -7982,8 +9612,8 @@ type UpdateAuthorizerInput struct { // The identifier of the Authorizer resource. AuthorizerId *string `location:"uri" locationName:"authorizer_id" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The RestApi identifier for the Authorizer resource. @@ -8026,8 +9656,8 @@ type UpdateBasePathMappingInput struct { // The domain name of the BasePathMapping resource to change. DomainName *string `location:"uri" locationName:"domain_name" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` } @@ -8064,8 +9694,8 @@ type UpdateClientCertificateInput struct { // The identifier of the ClientCertificate resource to be updated. ClientCertificateId *string `location:"uri" locationName:"clientcertificate_id" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` } @@ -8096,12 +9726,12 @@ func (s *UpdateClientCertificateInput) Validate() error { type UpdateDeploymentInput struct { _ struct{} `type:"structure"` - // The replacment identifier for the Deployment resource to change information + // The replacement identifier for the Deployment resource to change information // about. DeploymentId *string `location:"uri" locationName:"deployment_id" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The replacement identifier of the RestApi resource for the Deployment resource @@ -8142,8 +9772,8 @@ type UpdateDomainNameInput struct { // The name of the DomainName resource to be changed. DomainName *string `location:"uri" locationName:"domain_name" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` } @@ -8177,8 +9807,8 @@ type UpdateIntegrationInput struct { // Represents an update integration request's HTTP method. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // Represents an update integration request's resource identifier. @@ -8224,8 +9854,8 @@ type UpdateIntegrationResponseInput struct { // Specifies an update integration response request's HTTP method. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // Specifies an update integration response request's resource identifier. @@ -8274,11 +9904,11 @@ func (s *UpdateIntegrationResponseInput) Validate() error { type UpdateMethodInput struct { _ struct{} `type:"structure"` - // The HTTP verb that identifies the Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The Resource identifier for the Method resource. @@ -8321,11 +9951,11 @@ func (s *UpdateMethodInput) Validate() error { type UpdateMethodResponseInput struct { _ struct{} `type:"structure"` - // The HTTP verb identifier for the parent Method resource. + // The HTTP verb of the Method resource. HttpMethod *string `location:"uri" locationName:"http_method" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The Resource identifier for the MethodResponse resource. @@ -8334,7 +9964,7 @@ type UpdateMethodResponseInput struct { // The RestApi identifier for the MethodResponse resource. RestApiId *string `location:"uri" locationName:"restapi_id" type:"string" required:"true"` - // The status code identifier for the MethodResponse resource. + // The status code for the MethodResponse resource. StatusCode *string `location:"uri" locationName:"status_code" type:"string" required:"true"` } @@ -8377,8 +10007,8 @@ type UpdateModelInput struct { // The name of the model to update. ModelName *string `location:"uri" locationName:"model_name" type:"string" required:"true"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The RestApi identifier under which the model exists. @@ -8415,8 +10045,8 @@ func (s *UpdateModelInput) Validate() error { type UpdateResourceInput struct { _ struct{} `type:"structure"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The identifier of the Resource resource. @@ -8456,8 +10086,8 @@ func (s *UpdateResourceInput) Validate() error { type UpdateRestApiInput struct { _ struct{} `type:"structure"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The ID of the RestApi you want to update. @@ -8491,8 +10121,8 @@ func (s *UpdateRestApiInput) Validate() error { type UpdateStageInput struct { _ struct{} `type:"structure"` - // A list of operations describing the updates to apply to the specified resource. - // The patches are applied in the order specified in the list. + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` // The identifier of the RestApi resource for the Stage resource to change information @@ -8529,7 +10159,198 @@ func (s *UpdateStageInput) Validate() error { return nil } -// The authorizer type. Only current value is TOKEN. +// The PATCH request to grant a temporary extension to the reamining quota of +// a usage plan associated with a specified API key. +type UpdateUsageInput struct { + _ struct{} `type:"structure"` + + // The identifier of the API key associated with the usage plan in which a temporary + // extension is granted to the remaining quota. + KeyId *string `location:"uri" locationName:"keyId" type:"string" required:"true"` + + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. + PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` + + // The Id of the usage plan associated with the usage data. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateUsageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateUsageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateUsageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateUsageInput"} + if s.KeyId == nil { + invalidParams.Add(request.NewErrParamRequired("KeyId")) + } + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// The PATCH request to update a usage plan of a given plan Id. +type UpdateUsagePlanInput struct { + _ struct{} `type:"structure"` + + // A list of update operations to be applied to the specified resource and in + // the order specified in this list. + PatchOperations []*PatchOperation `locationName:"patchOperations" type:"list"` + + // The Id of the to-be-updated usage plan. + UsagePlanId *string `location:"uri" locationName:"usageplanId" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateUsagePlanInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateUsagePlanInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateUsagePlanInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateUsagePlanInput"} + if s.UsagePlanId == nil { + invalidParams.Add(request.NewErrParamRequired("UsagePlanId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// Represents the usage data of a usage plan. +// +// Create and Use Usage Plans (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html), +// Manage Usage in a Usage Plan (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-usage-plans-with-console.html#api-gateway-usage-plan-manage-usage) +type Usage struct { + _ struct{} `type:"structure"` + + // The ending date of the usage data. + EndDate *string `locationName:"endDate" type:"string"` + + // The usage data, as daily logs of used and remaining quotas, over the specified + // time interval indexed over the API keys in a usage plan. For example, {..., + // "values" : { "{api_key}" : [ [0, 100], [10, 90], [100, 10]]}, where {api_key} + // stands for an API key value and the daily log entry is of the format [used + // quota, remaining quota]. + Items map[string][][]*int64 `locationName:"values" type:"map"` + + Position *string `locationName:"position" type:"string"` + + // The starting date of the usage data. + StartDate *string `locationName:"startDate" type:"string"` + + // The plan Id associated with this usage data. + UsagePlanId *string `locationName:"usagePlanId" type:"string"` +} + +// String returns the string representation +func (s Usage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Usage) GoString() string { + return s.String() +} + +// Represents a usage plan than can specify who can assess associated API stages +// with specified request limits and quotas. +// +// In a usage plan, you associate an API by specifying the API's Id and a +// stage name of the specified API. You add plan customers by adding API keys +// to the plan. +// +// Create and Use Usage Plans (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html) +type UsagePlan struct { + _ struct{} `type:"structure"` + + // The associated API stages of a usage plan. + ApiStages []*ApiStage `locationName:"apiStages" type:"list"` + + // The description of a usage plan. + Description *string `locationName:"description" type:"string"` + + // The identifier of a UsagePlan resource. + Id *string `locationName:"id" type:"string"` + + // The name of a usage plan. + Name *string `locationName:"name" type:"string"` + + // The maximum number of permitted requests per a given unit time interval. + Quota *QuotaSettings `locationName:"quota" type:"structure"` + + // The request throttle limits of a usage plan. + Throttle *ThrottleSettings `locationName:"throttle" type:"structure"` +} + +// String returns the string representation +func (s UsagePlan) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UsagePlan) GoString() string { + return s.String() +} + +// Represents a usage plan key to identify a plan customer. +// +// To associate an API stage with a selected API key in a usage plan, you +// must create a UsagePlanKey resource to represent the selected ApiKey. +// +// " Create and Use Usage Plans (http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html) +type UsagePlanKey struct { + _ struct{} `type:"structure"` + + // The Id of a usage plan key. + Id *string `locationName:"id" type:"string"` + + // The name of a usage plan key. + Name *string `locationName:"name" type:"string"` + + // The type of a usage plan key. Currently, the valid key type is API_KEY. + Type *string `locationName:"type" type:"string"` + + // The value of a usage plan key. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s UsagePlanKey) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UsagePlanKey) GoString() string { + return s.String() +} + +const ( + // @enum ApiKeysFormat + ApiKeysFormatCsv = "csv" +) + +// The authorizer type. the only current value is TOKEN. const ( // @enum AuthorizerType AuthorizerTypeToken = "TOKEN" @@ -8588,6 +10409,15 @@ const ( PutModeOverwrite = "overwrite" ) +const ( + // @enum QuotaPeriodType + QuotaPeriodTypeDay = "DAY" + // @enum QuotaPeriodType + QuotaPeriodTypeWeek = "WEEK" + // @enum QuotaPeriodType + QuotaPeriodTypeMonth = "MONTH" +) + const ( // @enum UnauthorizedCacheControlHeaderStrategy UnauthorizedCacheControlHeaderStrategyFailWith403 = "FAIL_WITH_403" diff --git a/vendor/github.com/aws/aws-sdk-go/service/apigateway/service.go b/vendor/github.com/aws/aws-sdk-go/service/apigateway/service.go index 3372a2f7437e..27539d8e2a8a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/apigateway/service.go +++ b/vendor/github.com/aws/aws-sdk-go/service/apigateway/service.go @@ -11,11 +11,11 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/restjson" ) -// Amazon API Gateway helps developers deliver robust, secure and scalable mobile -// and web application backends. Amazon API Gateway allows developers to securely -// connect mobile and web applications to APIs that run on AWS Lambda, Amazon -// EC2, or other publicly addressable web services that are hosted outside of -// AWS. +// Amazon API Gateway helps developers deliver robust, secure, and scalable +// mobile and web application back ends. Amazon API Gateway allows developers +// to securely connect mobile and web applications to APIs that run on AWS Lambda, +// Amazon EC2, or other publicly addressable web services that are hosted outside +// of AWS. //The service client's operations are safe to be used concurrently. // It is not safe to mutate any of the client's properties though. type APIGateway struct { diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go b/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go index c3fea11fb710..8b1fd81857e1 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go @@ -1274,12 +1274,17 @@ func (c *ECS) RegisterTaskDefinitionRequest(input *RegisterTaskDefinitionInput) // see Amazon ECS Task Definitions (http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_defintions.html) // in the Amazon EC2 Container Service Developer Guide. // -// You may also specify an IAM role for your task with the taskRoleArn parameter. +// You can specify an IAM role for your task with the taskRoleArn parameter. // When you specify an IAM role for a task, its containers can then use the // latest versions of the AWS CLI or SDKs to make API requests to the AWS services // that are specified in the IAM policy associated with the role. For more information, // see IAM Roles for Tasks (http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) // in the Amazon EC2 Container Service Developer Guide. +// +// You can specify a Docker networking mode for the containers in your task +// definition with the networkMode parameter. The available network modes correspond +// to those described in Network settings (https://docs.docker.com/engine/reference/run/#/network-settings) +// in the Docker run reference. func (c *ECS) RegisterTaskDefinition(input *RegisterTaskDefinitionInput) (*RegisterTaskDefinitionOutput, error) { req, out := c.RegisterTaskDefinitionRequest(input) err := req.Send() @@ -1827,8 +1832,8 @@ type ContainerDefinition struct { _ struct{} `type:"structure"` // The command that is passed to the container. This parameter maps to Cmd in - // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the COMMAND parameter to docker run (https://docs.docker.com/reference/commandline/run/). // For more information, see https://docs.docker.com/reference/builder/#cmd // (https://docs.docker.com/reference/builder/#cmd). @@ -1839,8 +1844,8 @@ type ContainerDefinition struct { // amount of CPU to reserve for a container, and containers share unallocated // CPU units with other containers on the instance with the same ratio as their // allocated amount. This parameter maps to CpuShares in the Create a container - // (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --cpu-shares option to docker run (https://docs.docker.com/reference/commandline/run/). // // You can determine the number of CPU units that are available per EC2 instance @@ -1876,25 +1881,25 @@ type ContainerDefinition struct { Cpu *int64 `locationName:"cpu" type:"integer"` // When this parameter is true, networking is disabled within the container. - // This parameter maps to NetworkDisabled in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/). + // This parameter maps to NetworkDisabled in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/). DisableNetworking *bool `locationName:"disableNetworking" type:"boolean"` // A list of DNS search domains that are presented to the container. This parameter - // maps to DnsSearch in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // maps to DnsSearch in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --dns-search option to docker run (https://docs.docker.com/reference/commandline/run/). DnsSearchDomains []*string `locationName:"dnsSearchDomains" type:"list"` // A list of DNS servers that are presented to the container. This parameter - // maps to Dns in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // maps to Dns in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --dns option to docker run (https://docs.docker.com/reference/commandline/run/). DnsServers []*string `locationName:"dnsServers" type:"list"` // A key/value map of labels to add to the container. This parameter maps to - // Labels in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // Labels in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --label option to docker run (https://docs.docker.com/reference/commandline/run/). // This parameter requires version 1.18 of the Docker Remote API or greater // on your container instance. To check the Docker Remote API version on your @@ -1904,8 +1909,8 @@ type ContainerDefinition struct { // A list of strings to provide custom labels for SELinux and AppArmor multi-level // security systems. This parameter maps to SecurityOpt in the Create a container - // (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --security-opt option to docker run (https://docs.docker.com/reference/commandline/run/). // // The Amazon ECS container agent running on a container instance must register @@ -1921,16 +1926,16 @@ type ContainerDefinition struct { // agent or enter your commands and arguments as command array items instead. // // The entry point that is passed to the container. This parameter maps to - // Entrypoint in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // Entrypoint in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --entrypoint option to docker run (https://docs.docker.com/reference/commandline/run/). // For more information, see https://docs.docker.com/reference/builder/#entrypoint // (https://docs.docker.com/reference/builder/#entrypoint). EntryPoint []*string `locationName:"entryPoint" type:"list"` // The environment variables to pass to a container. This parameter maps to - // Env in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // Env in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --env option to docker run (https://docs.docker.com/reference/commandline/run/). // // We do not recommend using plain text environment variables for sensitive @@ -1953,14 +1958,14 @@ type ContainerDefinition struct { // A list of hostnames and IP address mappings to append to the /etc/hosts file // on the container. This parameter maps to ExtraHosts in the Create a container - // (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --add-host option to docker run (https://docs.docker.com/reference/commandline/run/). ExtraHosts []*HostEntry `locationName:"extraHosts" type:"list"` // The hostname to use for your container. This parameter maps to Hostname in - // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --hostname option to docker run (https://docs.docker.com/reference/commandline/run/). Hostname *string `locationName:"hostname" type:"string"` @@ -1969,8 +1974,8 @@ type ContainerDefinition struct { // Other repositories are specified with repository-url/image:tag . Up to 255 // letters (uppercase and lowercase), numbers, hyphens, underscores, colons, // periods, forward slashes, and number signs are allowed. This parameter maps - // to Image in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // to Image in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the IMAGE parameter of docker run (https://docs.docker.com/reference/commandline/run/). // // Images in official repositories on Docker Hub use a single name (for example, @@ -1989,8 +1994,8 @@ type ContainerDefinition struct { // Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores // are allowed for each name and alias. For more information on linking Docker // containers, see https://docs.docker.com/userguide/dockerlinks/ (https://docs.docker.com/userguide/dockerlinks/). - // This parameter maps to Links in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // This parameter maps to Links in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --link option to docker run (https://docs.docker.com/reference/commandline/run/). // // Containers that are collocated on a single container instance may be able @@ -2000,8 +2005,8 @@ type ContainerDefinition struct { Links []*string `locationName:"links" type:"list"` // The log configuration specification for the container. This parameter maps - // to LogConfig in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // to LogConfig in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --log-driver option to docker run (https://docs.docker.com/reference/commandline/run/). // By default, containers use the same logging driver that the Docker daemon // uses; however the container may use a different logging driver than the Docker @@ -2030,19 +2035,49 @@ type ContainerDefinition struct { // in the Amazon EC2 Container Service Developer Guide. LogConfiguration *LogConfiguration `locationName:"logConfiguration" type:"structure"` - // The number of MiB of memory to reserve for the container. You must specify - // a non-zero integer for this parameter; the Docker daemon reserves a minimum - // of 4 MiB of memory for a container, so you should not specify fewer than - // 4 MiB of memory for your containers. If your container attempts to exceed - // the memory allocated here, the container is killed. This parameter maps to - // Memory in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // The hard limit (in MiB) of memory to present to the container. If your container + // attempts to exceed the memory specified here, the container is killed. This + // parameter maps to Memory in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --memory option to docker run (https://docs.docker.com/reference/commandline/run/). + // + // You must specify a non-zero integer for one or both of memory or memoryReservation + // in container definitions. If you specify both, memory must be greater than + // memoryReservation. If you specify memoryReservation, then that value is subtracted + // from the available memory resources for the container instance on which the + // container is placed; otherwise, the value of memory is used. + // + // The Docker daemon reserves a minimum of 4 MiB of memory for a container, + // so you should not specify fewer than 4 MiB of memory for your containers. Memory *int64 `locationName:"memory" type:"integer"` + // The soft limit (in MiB) of memory to reserve for the container. When system + // memory is under heavy contention, Docker attempts to keep the container memory + // to this soft limit; however, your container can consume more memory when + // it needs to, up to either the hard limit specified with the memory parameter + // (if applicable), or all of the available memory on the container instance, + // whichever comes first. This parameter maps to MemoryReservation in the Create + // a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) + // and the --memory-reservation option to docker run (https://docs.docker.com/reference/commandline/run/). + // + // You must specify a non-zero integer for one or both of memory or memoryReservation + // in container definitions. If you specify both, memory must be greater than + // memoryReservation. If you specify memoryReservation, then that value is subtracted + // from the available memory resources for the container instance on which the + // container is placed; otherwise, the value of memory is used. + // + // For example, if your container normally uses 128 MiB of memory, but occasionally + // bursts to 256 MiB of memory for short periods of time, you can set a memoryReservation + // of 128 MiB, and a memory hard limit of 300 MiB. This configuration would + // allow the container to only reserve 128 MiB of memory from the remaining + // resources on the container instance, but also allow the container to consume + // more memory resources when needed. + MemoryReservation *int64 `locationName:"memoryReservation" type:"integer"` + // The mount points for data volumes in your container. This parameter maps - // to Volumes in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // to Volumes in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --volume option to docker run (https://docs.docker.com/reference/commandline/run/). MountPoints []*MountPoint `locationName:"mountPoints" type:"list"` @@ -2050,16 +2085,20 @@ type ContainerDefinition struct { // in a task definition, the name of one container can be entered in the links // of another container to connect the containers. Up to 255 letters (uppercase // and lowercase), numbers, hyphens, and underscores are allowed. This parameter - // maps to name in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // maps to name in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --name option to docker run (https://docs.docker.com/reference/commandline/run/). Name *string `locationName:"name" type:"string"` // The list of port mappings for the container. Port mappings allow containers // to access ports on the host container instance to send or receive traffic. - // This parameter maps to PortBindings in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // This parameter maps to PortBindings in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --publish option to docker run (https://docs.docker.com/reference/commandline/run/). + // If the network mode of a task definition is set to none, then you cannot + // specify port mappings. If the network mode of a task definition is set to + // host, then host ports must either be undefined or they must match the container + // port in the port mapping. // // After a task reaches the RUNNING status, manual and automatic host and // container port assignments are visible in the Network Bindings section of @@ -2069,21 +2108,21 @@ type ContainerDefinition struct { // When this parameter is true, the container is given elevated privileges on // the host container instance (similar to the root user). This parameter maps - // to Privileged in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // to Privileged in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --privileged option to docker run (https://docs.docker.com/reference/commandline/run/). Privileged *bool `locationName:"privileged" type:"boolean"` // When this parameter is true, the container is given read-only access to its // root file system. This parameter maps to ReadonlyRootfs in the Create a container - // (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --read-only option to docker run. ReadonlyRootFilesystem *bool `locationName:"readonlyRootFilesystem" type:"boolean"` // A list of ulimits to set in the container. This parameter maps to Ulimits - // in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --ulimit option to docker run (https://docs.docker.com/reference/commandline/run/). // Valid naming values are displayed in the Ulimit data type. This parameter // requires version 1.18 of the Docker Remote API or greater on your container @@ -2093,20 +2132,20 @@ type ContainerDefinition struct { Ulimits []*Ulimit `locationName:"ulimits" type:"list"` // The user name to use inside the container. This parameter maps to User in - // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --user option to docker run (https://docs.docker.com/reference/commandline/run/). User *string `locationName:"user" type:"string"` // Data volumes to mount from another container. This parameter maps to VolumesFrom - // in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --volumes-from option to docker run (https://docs.docker.com/reference/commandline/run/). VolumesFrom []*VolumeFrom `locationName:"volumesFrom" type:"list"` // The working directory in which to run commands inside the container. This - // parameter maps to WorkingDir in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.19/#create-a-container) - // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.19/) + // parameter maps to WorkingDir in the Create a container (https://docs.docker.com/reference/api/docker_remote_api_v1.23/#create-a-container) + // section of the Docker Remote API (https://docs.docker.com/reference/api/docker_remote_api_v1.23/) // and the --workdir option to docker run (https://docs.docker.com/reference/commandline/run/). WorkingDirectory *string `locationName:"workingDirectory" type:"string"` } @@ -3788,6 +3827,23 @@ type RegisterTaskDefinitionInput struct { // hyphens, and underscores are allowed. Family *string `locationName:"family" type:"string" required:"true"` + // The Docker networking mode to use for the containers in the task. The valid + // values are none, bridge, and host. + // + // The default Docker network mode is bridge. If the network mode is set to + // none, you cannot specify port mappings in your container definitions, and + // the task's containers do not have external connectivity. The host network + // mode offers the highest networking performance for containers because they + // use the host network stack instead of the virtualized network stack provided + // by the bridge mode; however, exposed container ports are mapped directly + // to the corresponding host port, so you cannot take advantage of dynamic host + // port mappings or run multiple instantiations of the same task on a single + // container instance if port mappings are used. + // + // For more information, see Network settings (https://docs.docker.com/engine/reference/run/#network-settings) + // in the Docker run reference. + NetworkMode *string `locationName:"networkMode" type:"string" enum:"NetworkMode"` + // The Amazon Resource Name (ARN) of the IAM role that containers in this task // can assume. All containers in this task are granted the permissions that // are specified in this role. @@ -4389,6 +4445,18 @@ type TaskDefinition struct { // The family of your task definition, used as the definition name. Family *string `locationName:"family" type:"string"` + // The Docker networking mode to use for the containers in the task. The valid + // values are none, bridge, and host. + // + // If the network mode is none, the containers do not have external connectivity. + // The default Docker network mode is bridge. The host network mode offers the + // highest networking performance for containers because it uses the host network + // stack instead of the virtualized network stack provided by the bridge mode. + // + // For more information, see Network settings (https://docs.docker.com/engine/reference/run/#network-settings) + // in the Docker run reference. + NetworkMode *string `locationName:"networkMode" type:"string" enum:"NetworkMode"` + // The container instance attributes required by your task. RequiresAttributes []*Attribute `locationName:"requiresAttributes" type:"list"` @@ -4727,6 +4795,17 @@ const ( LogDriverFluentd = "fluentd" // @enum LogDriver LogDriverAwslogs = "awslogs" + // @enum LogDriver + LogDriverSplunk = "splunk" +) + +const ( + // @enum NetworkMode + NetworkModeBridge = "bridge" + // @enum NetworkMode + NetworkModeHost = "host" + // @enum NetworkMode + NetworkModeNone = "none" ) const ( diff --git a/vendor/github.com/aws/aws-sdk-go/service/elbv2/api.go b/vendor/github.com/aws/aws-sdk-go/service/elbv2/api.go index 17e502a69ed8..77cd413fa294 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/elbv2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/elbv2/api.go @@ -4005,9 +4005,9 @@ type TargetGroupAttribute struct { // The name of the attribute. // - // deregistration_delay.timeout_seconds - The time to wait for in-flight - // requests to complete while deregistering a target. The state of a deregistering - // target is draining. The range is 0-3600 seconds. The default value is 300 + // deregistration_delay.timeout_seconds - The amount time for Elastic Load + // Balancing to wait before changing the state of a deregistering target from + // draining to unused. The range is 0-3600 seconds. The default value is 300 // seconds. // // stickiness.enabled - Indicates whether sticky sessions are enabled. diff --git a/vendor/github.com/aws/aws-sdk-go/service/kms/api.go b/vendor/github.com/aws/aws-sdk-go/service/kms/api.go index 447d2f886e60..fb2d1a356f3f 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/kms/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/kms/api.go @@ -3421,7 +3421,7 @@ type ImportKeyMaterialInput struct { // expires, AWS KMS deletes the key material and the CMK becomes unusable. You // must omit this parameter when the ExpirationModel parameter is set to KEY_MATERIAL_DOES_NOT_EXPIRE. // Otherwise it is required. - ValidTo *time.Time `type:"timestamp" timestampFormat:"unix" required:"true"` + ValidTo *time.Time `type:"timestamp" timestampFormat:"unix"` } // String returns the string representation @@ -3455,9 +3455,6 @@ func (s *ImportKeyMaterialInput) Validate() error { if s.KeyId != nil && len(*s.KeyId) < 1 { invalidParams.Add(request.NewErrParamMinLen("KeyId", 1)) } - if s.ValidTo == nil { - invalidParams.Add(request.NewErrParamRequired("ValidTo")) - } if invalidParams.Len() > 0 { return invalidParams diff --git a/vendor/vendor.json b/vendor/vendor.json index 750c1df84965..c1074eabeddb 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -347,417 +347,554 @@ { "checksumSHA1": "QhFYdDb2z6DMbZPsDi9oCQS9nRY=", "path": "github.com/aws/aws-sdk-go", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z", - "version": "v1.3.1" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { - "checksumSHA1": "k4BkX61fhl/oX9X0lP7GFSvdz1s=", + "checksumSHA1": "dSo0vFXJGuTtd6H80q8ZczLszJM=", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "dkfyy7aRNZ6BmUZ4ZdLIcMMXiPA=", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "RsYlRfQceaAgqjIrExwNsb/RBEM=", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "gNWirlrTfSLbOe421hISBAhTqa4=", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "dNZNaOPfBPnzE2CBnfhXXZ9g9jU=", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "KQiUK/zr3mqnAXD7x/X55/iNme0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "4Ipx+5xN0gso+cENC2MHMWmQlR4=", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "nCMd1XKjgV21bEl7J8VZFqTV8PE=", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "U0SthWum+t9ACanK7SDJOg3dO6M=", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "NyUg1P8ZS/LHAAQAk/4C5O4X3og=", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "tBdFneml1Vn7uvezcktsa+hUsGg=", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "7lla+sckQeF18wORAGuU2fFMlp4=", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "Bm6UrYb2QCzpYseLwwgw6aetgRc=", "path": "github.com/aws/aws-sdk-go/private/endpoints", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "uNmSKXAF8B9HWEciW+iyUwZ99qQ=", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "L7xWYwx0jNQnzlYHwBS+1q6DcCI=", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "H9TymcQkQnXSXSVfjggiiS4bpzM=", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "isoix7lTx4qIq2zI2xFADtti5SI=", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "5xzix1R8prUyWxgLnzUQoxTsfik=", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "TW/7U+/8ormL7acf6z2rv2hDD+s=", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "oUOTWZIpPJiGjc9p/hntdBDvS10=", "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "Y6Db2GGfGD9LPpcJIPj8vXE8BbQ=", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "eUEkjyMPAuekKBE4ou+nM9tXEas=", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "F6mth+G7dXN1GI+nktaGo8Lx8aE=", "path": "github.com/aws/aws-sdk-go/private/signer/v2", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "path": "github.com/aws/aws-sdk-go/private/waiter", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { - "checksumSHA1": "j8CUd3jhZ8K+cI8fy785NmqJyzg=", + "checksumSHA1": "DXwm+kmVCiuvvGCcUTeZD/L31Kk=", "path": "github.com/aws/aws-sdk-go/service/apigateway", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "qoTWohhN8wMZvdMAbwi+B5YhQJ0=", "path": "github.com/aws/aws-sdk-go/service/applicationautoscaling", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "ygJl5okbywr9j3Cl2GTI/e8f94c=", "path": "github.com/aws/aws-sdk-go/service/autoscaling", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "vp/AYdsQnZtoPqtX86VsgmLIx1w=", "path": "github.com/aws/aws-sdk-go/service/cloudformation", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "CpWQcLIxUTtkF6NBRg0QwdeSA/k=", "path": "github.com/aws/aws-sdk-go/service/cloudfront", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "eCFTaV9GKqv/UEzwRgFFUaFz098=", "path": "github.com/aws/aws-sdk-go/service/cloudtrail", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "G9CmCfw00Bjz0TtJsEnxGE6mv/0=", "path": "github.com/aws/aws-sdk-go/service/cloudwatch", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "mWNJKpt18ASs9/RhnIjILcsGlng=", "path": "github.com/aws/aws-sdk-go/service/cloudwatchevents", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "sP/qEaDICVBV3rRw2sl759YI0iw=", "path": "github.com/aws/aws-sdk-go/service/cloudwatchlogs", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "p5a/DcdUvhTx0PCRR+/CRXk9g6c=", "path": "github.com/aws/aws-sdk-go/service/codecommit", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "N8Sgq+xG2vYJdKBikM3yQuIBZfs=", "path": "github.com/aws/aws-sdk-go/service/codedeploy", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "i4hrcsFXLAQXzaxvWh6+BG8XcIU=", "path": "github.com/aws/aws-sdk-go/service/directoryservice", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "y+pZPK8hcTDwq1zHuRduWE14flw=", "path": "github.com/aws/aws-sdk-go/service/dynamodb", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "lJYBdjCwoqPpmmjNyW2yYk9VGiY=", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "RUfkmRJpf1l6rHJfh/86gtG4Was=", "path": "github.com/aws/aws-sdk-go/service/ecr", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { - "checksumSHA1": "n6llxIMIGbjTer/33Zmz4cNKVQA=", + "checksumSHA1": "KRHODSkYmdWutb+y13JhuKlonNY=", "path": "github.com/aws/aws-sdk-go/service/ecs", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "1vOgFGxLhjNe6BK3RJaV1OqisCs=", "path": "github.com/aws/aws-sdk-go/service/efs", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "rjSScNzMTvEHv7Lk5KcxDpNU5EE=", "path": "github.com/aws/aws-sdk-go/service/elasticache", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "RZF1yHtJhAqaMwbeAM/6BdLLavk=", "path": "github.com/aws/aws-sdk-go/service/elasticbeanstalk", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "VAlXnW+WxxWRcCv4xsCoox2kgE0=", "path": "github.com/aws/aws-sdk-go/service/elasticsearchservice", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "qHuJHGUAuuizD9834MP3gVupfdo=", "path": "github.com/aws/aws-sdk-go/service/elastictranscoder", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "YiNiSOILzSOaKB4JwdM4SDw7daM=", "path": "github.com/aws/aws-sdk-go/service/elb", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { - "checksumSHA1": "DLD6/EwnTkIR6HGaYKYs96lCD+Q=", + "checksumSHA1": "DdsbJgngbL7Ce18ipxreRsf3lYo=", "path": "github.com/aws/aws-sdk-go/service/elbv2", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "MA6U/Vj0D00yihMHD6bXKyjtfeE=", "path": "github.com/aws/aws-sdk-go/service/emr", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "TtIAgZ+evpkKB5bBYCB69k0wZoU=", "path": "github.com/aws/aws-sdk-go/service/firehose", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "B1EtgBrv//gYqA+Sp6a/SK2zLO4=", "path": "github.com/aws/aws-sdk-go/service/glacier", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "kXJ9ycLAIj0PFSFbfrA/LR/hIi8=", "path": "github.com/aws/aws-sdk-go/service/iam", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "2n5/m0ClE4OyQRNdjfLwg+nSY3o=", "path": "github.com/aws/aws-sdk-go/service/kinesis", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { - "checksumSHA1": "IUiewu7NPRaPPGtWkXHkvVU+80c=", + "checksumSHA1": "l6GbB/V5dPb3l+Nrb70wzyrYAgc=", "path": "github.com/aws/aws-sdk-go/service/kms", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "Qpi347xz5FIQISq73dZSdIf47AU=", "path": "github.com/aws/aws-sdk-go/service/lambda", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "aLwDFgrPzIBidURxso1ujcr2pDs=", "path": "github.com/aws/aws-sdk-go/service/opsworks", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "abtQbJdjxwPxvt4p/X0My6FtfZI=", "path": "github.com/aws/aws-sdk-go/service/rds", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "mgImZ/bluUOY9GpQ/oAnscIXwrA=", "path": "github.com/aws/aws-sdk-go/service/redshift", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "y6jKUvrpTJxj5uh6OqQ4FujhCHU=", "path": "github.com/aws/aws-sdk-go/service/route53", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "imxJucuPrgaPRMPtAgsu+Y7soB4=", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "o+bjuT6ycywUf+vXY9hYK4Z3okE=", "path": "github.com/aws/aws-sdk-go/service/ses", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "DW5kDRWLA2yAgYh9vsI+0uVqq/Q=", "path": "github.com/aws/aws-sdk-go/service/simpledb", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "+ic7vevBfganFLENR29pJaEf4Tw=", "path": "github.com/aws/aws-sdk-go/service/sns", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "oLAlquYlQzgYFS9ochS/iQ9+uXY=", "path": "github.com/aws/aws-sdk-go/service/sqs", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "checksumSHA1": "nH/itbdeFHpl4ysegdtgww9bFSA=", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "f80e7d0182a463dff0c0da6bbed57f21369d4346", - "revisionTime": "2016-08-11T16:24:59Z" + "revision": "35c21ff262580265c1d77095d6f712605fd0c3f4", + "revisionTime": "2016-08-16T21:54:33Z", + "version": "v1.4.2", + "versionExact": "v1.4.2" }, { "path": "github.com/bgentry/speakeasy", From e37dbefd90994173dc0c614f9884f29504ed2200 Mon Sep 17 00:00:00 2001 From: f440 Date: Sat, 20 Aug 2016 20:03:20 +0900 Subject: [PATCH 057/100] Fix file extension (#8343) --- .../docs/providers/packet/r/{volume.html => volume.html.markdown} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename website/source/docs/providers/packet/r/{volume.html => volume.html.markdown} (100%) diff --git a/website/source/docs/providers/packet/r/volume.html b/website/source/docs/providers/packet/r/volume.html.markdown similarity index 100% rename from website/source/docs/providers/packet/r/volume.html rename to website/source/docs/providers/packet/r/volume.html.markdown From 8bd2a249ce1e96959f72d5ec1ec4d68c83295189 Mon Sep 17 00:00:00 2001 From: Andrew Langhorn Date: Sun, 21 Aug 2016 14:21:02 +0100 Subject: [PATCH 058/100] Add note to use Server-Defined-Cipher-Order The Terraform documentation, rather correctly, refers to a list of options you can pass to an Elastic Load Balancer from the AWS documentation. All but one of these options works; 'Server Order Preference' doesn't work, because the API refers to it as 'Server-Defined-Cipher-Order'. Add a note to explain this, at least as a temporary solution. Fixes #8340. --- .../providers/aws/r/lb_ssl_negotiation_policy.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/docs/providers/aws/r/lb_ssl_negotiation_policy.html.markdown b/website/source/docs/providers/aws/r/lb_ssl_negotiation_policy.html.markdown index e45b00a7ba5d..863ef52ea803 100644 --- a/website/source/docs/providers/aws/r/lb_ssl_negotiation_policy.html.markdown +++ b/website/source/docs/providers/aws/r/lb_ssl_negotiation_policy.html.markdown @@ -76,6 +76,8 @@ balancer. To set your attributes, please see the [AWS Elastic Load Balancing Developer Guide](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-security-policy-table.html) for a listing of the supported SSL protocols, SSL options, and SSL ciphers. +~> **NOTE:** The AWS documentation references Server Order Preference, which the AWS Elastic Load Balancing API refers to as `Server-Defined-Cipher-Order`. If you wish to set Server Order Preference, use this value instead. + ## Attributes Reference The following attributes are exported: From 988b0325a1a235b5e0c0a70861668f396eacf186 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Sun, 21 Aug 2016 15:17:31 -0400 Subject: [PATCH 059/100] Add more output grammar and CLI examples --- .../source/docs/commands/output.html.markdown | 53 +++++++++++++++++-- .../source/docs/configuration/outputs.html.md | 28 ++++++---- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/website/source/docs/commands/output.html.markdown b/website/source/docs/commands/output.html.markdown index d42f7cae2194..79813d48c8e7 100644 --- a/website/source/docs/commands/output.html.markdown +++ b/website/source/docs/commands/output.html.markdown @@ -15,8 +15,9 @@ an output variable from the state file. Usage: `terraform output [options] [NAME]` -With no additional arguments, `output` will display all the outputs for the root module. -If an output `NAME` is specified, only the value of that output is printed. +With no additional arguments, `output` will display all the outputs for +the root module. If an output `NAME` is specified, only the value of that +output is printed. The command-line flags are all optional. The list of available flags are: @@ -24,9 +25,55 @@ The command-line flags are all optional. The list of available flags are: a key per output. If `NAME` is specified, only the output specified will be returned. This can be piped into tools such as `jq` for further processing. * `-state=path` - Path to the state file. Defaults to "terraform.tfstate". - Ignored when [remote state](/docs/state/remote/index.html) is used. + Ignored when [remote state](/docs/state/remote/index.html) is used. * `-module=module_name` - The module path which has needed output. By default this is the root path. Other modules can be specified by a period-separated list. Example: "foo" would reference the module "foo" but "foo.bar" would reference the "bar" module in the "foo" module. + +## Examples + +These examples assume the following Terraform output snippet. + +```ruby +output "lb_address" { + value = "${aws_alb.web.public_dns}" +} + +output "instance_ips" { + value = "${aws_instance.web.*.public_ip}" +} +``` + +To list all outputs: + +```text +$ terraform output +``` + +To query for the DNS address of the load balancer: + +```text +$ terraform output lb_address +my-app-alb-1657023003.us-east-1.elb.amazonaws.com +``` + +To query for all instance IP addresses: + +```text +$ terraform output instance_ips +test = [ + 54.43.114.12, + 52.122.13.4, + 52.4.116.53 +] +``` + +To query for a particular value in a list, use `-json` and a JSON +command-line parser such as [jq](https://stedolan.github.io/jq/). +For example, to query for the first instance's IP address: + +```text +$ terraform output -json instance_ips | jq '.value[0]' +``` diff --git a/website/source/docs/configuration/outputs.html.md b/website/source/docs/configuration/outputs.html.md index f3bc68e6ba0e..8cac18a8da7a 100644 --- a/website/source/docs/configuration/outputs.html.md +++ b/website/source/docs/configuration/outputs.html.md @@ -16,21 +16,31 @@ is covered in more detail in the This page covers configuration syntax for outputs. Terraform knows a lot about the infrastructure it manages. -Most resources have a handful or even a dozen or more attributes -associated with it. Outputs are a way to easily extract -information. +Most resources have attributes associated with them, and +outputs are a way to easily extract and query that information. -This page assumes you're familiar with the +This page assumes you are familiar with the [configuration syntax](/docs/configuration/syntax.html) already. ## Example -An output configuration looks like the following: +A simple output configuration looks like the following: -``` +```ruby output "address" { - value = "${aws_instance.web.public_dns}" + value = "${aws_instance.db.public_dns}" +} +``` + +This will output a string value corresponding to the public +DNS address of the Terraform-defined AWS instance named "db". It +is possible to export complex data types like maps and strings as +well: + +```ruby +output "addresses" { + value = ["${aws_instance.web.*.public_dns}"] } ``` @@ -54,7 +64,7 @@ These are the parameters that can be set: The full syntax is: -``` +```ruby output NAME { value = VALUE } @@ -65,7 +75,7 @@ output NAME { Outputs can be marked as containing sensitive material by setting the `sensitive` attribute to `true`, like this: -``` +```ruby output "sensitive" { sensitive = true value = VALUE From 74315d6d1bdc88a5a7c15ab70b3c6b90c3857183 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Mon, 22 Aug 2016 05:23:08 +0200 Subject: [PATCH 060/100] provider/archive: Fix doc sidebar title --- website/source/layouts/archive.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/layouts/archive.erb b/website/source/layouts/archive.erb index 07565d2c4839..11a92cc3c56a 100644 --- a/website/source/layouts/archive.erb +++ b/website/source/layouts/archive.erb @@ -7,7 +7,7 @@ > - Template Provider + Archive Provider > From 61f885aa8640e2c017a8055b50256b604cb582f4 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Mon, 22 Aug 2016 05:30:37 +0200 Subject: [PATCH 061/100] website: Add archive provider to sidebar and css --- website/source/assets/stylesheets/_docs.scss | 1 + website/source/layouts/docs.erb | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/website/source/assets/stylesheets/_docs.scss b/website/source/assets/stylesheets/_docs.scss index 773b2494f580..d417f2369c0b 100755 --- a/website/source/assets/stylesheets/_docs.scss +++ b/website/source/assets/stylesheets/_docs.scss @@ -7,6 +7,7 @@ body.page-sub{ } body.layout-commands-state, +body.layout-archive, body.layout-atlas, body.layout-aws, body.layout-azure, diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 20b0b578cf52..f97a9f46f8b1 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -162,6 +162,10 @@ > Providers