From a7e0dcaa24594c062989d024b8be5ff4c544df74 Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Mon, 29 Apr 2019 14:22:38 -0700 Subject: [PATCH 1/8] add node groups --- products/compute/ansible.yaml | 4 + products/compute/api.yaml | 63 ++++++++++ products/compute/inspec.yaml | 2 + products/compute/terraform.yaml | 19 +++ .../examples/node_group_basic.tf.erb | 18 +++ .../resource_compute_node_group_test.go.erb | 116 ++++++++++++++++++ .../terraform/website-compiled/google.erb | 4 + 7 files changed, 226 insertions(+) create mode 100644 templates/terraform/examples/node_group_basic.tf.erb create mode 100644 third_party/terraform/tests/resource_compute_node_group_test.go.erb diff --git a/products/compute/ansible.yaml b/products/compute/ansible.yaml index 34bb138da6b3..caa1dc25408a 100644 --- a/products/compute/ansible.yaml +++ b/products/compute/ansible.yaml @@ -31,6 +31,8 @@ datasources: !ruby/object:Overrides::ResourceOverrides exclude: true MachineType: !ruby/object:Overrides::Ansible::ResourceOverride exclude: true + NodeGroup: !ruby/object:Overrides::Ansible::ResourceOverride + exclude: true NodeTemplate: !ruby/object:Overrides::Ansible::ResourceOverride exclude: true RegionAutoscaler: !ruby/object:Overrides::Ansible::ResourceOverride @@ -242,6 +244,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides exclude: true MachineType: !ruby/object:Overrides::Ansible::ResourceOverride exclude: true + NodeGroup: !ruby/object:Overrides::Ansible::ResourceOverride + exclude: true NodeTemplate: !ruby/object:Overrides::Ansible::ResourceOverride exclude: true Region: !ruby/object:Overrides::Ansible::ResourceOverride diff --git a/products/compute/api.yaml b/products/compute/api.yaml index b72affd564ab..0e3b09252748 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -4823,6 +4823,69 @@ objects: description: | The default port used if the port number is not specified in the network endpoint. + - !ruby/object:Api::Resource + name: 'NodeGroup' + kind: 'compute#NodeGroup' + base_url: projects/{{project}}/zones/{{zone}}/nodeGroups + create_url: projects/{{project}}/zones/{{zone}}/nodeGroups?initialNodeCount={{size}} + has_self_link: true + description: | + Represents a NodeGroup resource to manage a group of sole-tenant nodes. + input: true + references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Sole-Tenant Nodes': 'https://cloud.google.com/compute/docs/nodes/' + api: 'https://cloud.google.com/compute/docs/reference/rest/v1/nodeGroups' + async: !ruby/object:Api::Async + operation: !ruby/object:Api::Async::Operation + kind: 'compute#operation' + path: 'name' + base_url: 'projects/{{project}}/zones/{{zone}}/operations/{{op_id}}' + wait_ms: 1000 + result: !ruby/object:Api::Async::Result + path: 'targetLink' + status: !ruby/object:Api::Async::Status + path: 'status' + complete: 'DONE' + allowed: + - 'PENDING' + - 'RUNNING' + - 'DONE' + error: !ruby/object:Api::Async::Error + path: 'error/errors' + message: 'message' + parameters: + - !ruby/object:Api::Type::ResourceRef + name: 'zone' + resource: 'Zone' + imports: 'selfLink' + required: true + description: | + Zone where this node group is located + properties: + - !ruby/object:Api::Type::Time + name: 'creationTimestamp' + description: 'Creation timestamp in RFC3339 text format.' + output: true + - !ruby/object:Api::Type::String + name: 'description' + description: 'An optional textual description of the resource.' + - !ruby/object:Api::Type::String + name: 'name' + description: 'Name of the resource.' + - !ruby/object:Api::Type::ResourceRef + name: 'nodeTemplate' + resource: 'NodeTemplate' + imports: 'selfLink' + required: true + description: | + The URL of the node template to which this node group belongs. + update_verb: :POST + update_url: 'projects/{{project}}/zones/{{zone}}/nodeGroups/{{name}}/setNodeTemplate' + - !ruby/object:Api::Type::Integer + name: 'size' + description: 'The total number of nodes in the node group.' + required: true - !ruby/object:Api::Resource name: 'NodeTemplate' kind: 'compute#nodeTemplate' diff --git a/products/compute/inspec.yaml b/products/compute/inspec.yaml index 1fc7f1f1a2fd..01c4296430a8 100644 --- a/products/compute/inspec.yaml +++ b/products/compute/inspec.yaml @@ -44,6 +44,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides exclude: true Network: !ruby/object:Overrides::Inspec::ResourceOverride exclude: true + NodeGroup: !ruby/object:Overrides::Inspec::ResourceOverride + exclude: true NodeTemplate: !ruby/object:Overrides::Inspec::ResourceOverride exclude: true Region: !ruby/object:Overrides::Inspec::ResourceOverride diff --git a/products/compute/terraform.yaml b/products/compute/terraform.yaml index 4f05678140ac..27d7f73ddea0 100644 --- a/products/compute/terraform.yaml +++ b/products/compute/terraform.yaml @@ -734,6 +734,25 @@ overrides: !ruby/object:Overrides::ResourceOverrides zone: !ruby/object:Overrides::Terraform::PropertyOverride required: false default_from_api: true + NodeGroup: !ruby/object:Overrides::Terraform::ResourceOverride + docs: !ruby/object:Provider::Terraform::Docs + warning: | + Due to limitations of the API is designed, Terraform cannot update the + number of nodes in a node group and changes to node group size either + through Terraform config or through external changes will cause + Terraform to delete and recreate the node group. + examples: + - !ruby/object:Provider::Terraform::Examples + name: "node_group_basic" + primary_resource_id: "nodes" + vars: + group_name: "soletenant-group" + template_name: "soletenant-tmpl" + properties: + zone: !ruby/object:Overrides::Terraform::PropertyOverride + required: false + default_from_api: true + custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb' NodeTemplate: !ruby/object:Overrides::Terraform::ResourceOverride examples: - !ruby/object:Provider::Terraform::Examples diff --git a/templates/terraform/examples/node_group_basic.tf.erb b/templates/terraform/examples/node_group_basic.tf.erb new file mode 100644 index 000000000000..fc303a227944 --- /dev/null +++ b/templates/terraform/examples/node_group_basic.tf.erb @@ -0,0 +1,18 @@ +data "google_compute_node_types" "central1a" { + zone = "us-central1-a" +} + +resource "google_compute_node_template" "soletenant-tmpl" { + name = "<%= ctx[:vars]['template_name'] %>" + region = "us-central1" + node_type = "${data.google_compute_node_types.central1a.names[0]}" +} + +resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['group_name'] %>" + zone = "us-central1-a" + description = "example google_compute_node_group for Terraform Google Provider" + + size = 1 + node_template = "${google_compute_node_template.soletenant-tmpl.self_link}" +} diff --git a/third_party/terraform/tests/resource_compute_node_group_test.go.erb b/third_party/terraform/tests/resource_compute_node_group_test.go.erb new file mode 100644 index 000000000000..364ada8efb69 --- /dev/null +++ b/third_party/terraform/tests/resource_compute_node_group_test.go.erb @@ -0,0 +1,116 @@ +<% autogen_exception -%> +package google + +import ( + "fmt" + "testing" + + "strings" + "time" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccComputeNodeGroup_updateNodeTemplate(t *testing.T) { + t.Parallel() + + groupName := acctest.RandomWithPrefix("group-") + tmplPrefix := acctest.RandomWithPrefix("tmpl-") + + var timeCreated time.Time + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeNodeGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccComputeNodeGroup_updateNodeTemplate(groupName, tmplPrefix, "tmpl1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeNodeGroupCreationTimeBefore(&timeCreated), + ), + }, + { + ResourceName: "google_compute_node_group.nodes", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeNodeGroup_updateNodeTemplate(groupName, tmplPrefix, "tmpl2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeNodeGroupCreationTimeBefore(&timeCreated), + ), + }, + { + ResourceName: "google_compute_node_group.nodes", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckComputeNodeGroupCreationTimeBefore(prevTimeCreated *time.Time) resource.TestCheckFunc { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_compute_node_group" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + timestampRaw, ok := rs.Primary.Attributes["creation_timestamp"] + if !ok { + return fmt.Errorf("expected creation_timestamp to be set in node group's state") + } + creationTimestamp, err := time.Parse(time.RFC3339Nano, timestampRaw) + if err != nil { + return fmt.Errorf("unexpected error while parsing creation_timestamp: %v", err) + } + + if prevTimeCreated.IsZero() { + *prevTimeCreated = creationTimestamp + return nil + } + + if creationTimestamp.After(prevTimeCreated.Add(time.Millisecond * 100)) { + return fmt.Errorf( + "Creation timestamp %q was after expected previous time of creation %q", + timestampRaw, prevTimeCreated.Format(time.RFC3339Nano)) + } + } + + return nil + } +} + +func testAccComputeNodeGroup_updateNodeTemplate(groupName, tmplPrefix, tmplToUse string) string { + return fmt.Sprintf(` +data "google_compute_node_types" "central1a" { + zone = "us-central1-a" +} + +resource "google_compute_node_template" "tmpl1" { + name = "%s-first" + region = "us-central1" + node_type = "${data.google_compute_node_types.central1a.names[0]}" +} + +resource "google_compute_node_template" "tmpl2" { + name = "%s-second" + region = "us-central1" + node_type = "${data.google_compute_node_types.central1a.names[0]}" +} + +resource "google_compute_node_group" "nodes" { + name = "%s" + zone = "us-central1-a" + description = "example google_compute_node_group for Terraform Google Provider" + + size = 1 + node_template = "${google_compute_node_template.%s.self_link}" +} +`, tmplPrefix, tmplPrefix, groupName, tmplToUse) +} diff --git a/third_party/terraform/website-compiled/google.erb b/third_party/terraform/website-compiled/google.erb index 6217265ba230..10bbd4969d47 100644 --- a/third_party/terraform/website-compiled/google.erb +++ b/third_party/terraform/website-compiled/google.erb @@ -451,6 +451,10 @@ google_compute_interconnect_attachment + > + google_compute_node_group + + > google_compute_node_template From 18742ed2c2d0e8e6ae7b8c18f2168df6120152df Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Tue, 30 Apr 2019 16:18:24 -0700 Subject: [PATCH 2/8] fix descriptions --- products/compute/api.yaml | 14 +++++++++----- products/compute/terraform.yaml | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/products/compute/api.yaml b/products/compute/api.yaml index 0e3b09252748..68ef32518813 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -4865,14 +4865,17 @@ objects: properties: - !ruby/object:Api::Type::Time name: 'creationTimestamp' - description: 'Creation timestamp in RFC3339 text format.' + description: | + Creation timestamp in RFC3339 text format. output: true - !ruby/object:Api::Type::String name: 'description' - description: 'An optional textual description of the resource.' + description: | + An optional textual description of the resource. - !ruby/object:Api::Type::String name: 'name' - description: 'Name of the resource.' + description: | + Name of the resource. - !ruby/object:Api::Type::ResourceRef name: 'nodeTemplate' resource: 'NodeTemplate' @@ -4884,7 +4887,8 @@ objects: update_url: 'projects/{{project}}/zones/{{zone}}/nodeGroups/{{name}}/setNodeTemplate' - !ruby/object:Api::Type::Integer name: 'size' - description: 'The total number of nodes in the node group.' + description: | + The total number of nodes in the node group. required: true - !ruby/object:Api::Resource name: 'NodeTemplate' @@ -4894,7 +4898,7 @@ objects: description: | Represents a NodeTemplate resource. Node templates specify properties for creating sole-tenant nodes, such as node type, vCPU and memory - requirments, node affinity labels, and region. + requirments, node affinity labels, and region. input: true references: !ruby/object:Api::Resource::ReferenceLinks guides: diff --git a/products/compute/terraform.yaml b/products/compute/terraform.yaml index 27d7f73ddea0..e1d5c1c9b0ce 100644 --- a/products/compute/terraform.yaml +++ b/products/compute/terraform.yaml @@ -737,7 +737,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides NodeGroup: !ruby/object:Overrides::Terraform::ResourceOverride docs: !ruby/object:Provider::Terraform::Docs warning: | - Due to limitations of the API is designed, Terraform cannot update the + Due to limitations of the API, Terraform cannot update the number of nodes in a node group and changes to node group size either through Terraform config or through external changes will cause Terraform to delete and recreate the node group. From c0c88b2085399e11c8745b7f9e8549374b0a6e02 Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Tue, 30 Apr 2019 16:20:10 -0700 Subject: [PATCH 3/8] make node size 0 in tests --- templates/terraform/examples/node_group_basic.tf.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/terraform/examples/node_group_basic.tf.erb b/templates/terraform/examples/node_group_basic.tf.erb index fc303a227944..781df439f2f4 100644 --- a/templates/terraform/examples/node_group_basic.tf.erb +++ b/templates/terraform/examples/node_group_basic.tf.erb @@ -13,6 +13,6 @@ resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" { zone = "us-central1-a" description = "example google_compute_node_group for Terraform Google Provider" - size = 1 + size = 0 node_template = "${google_compute_node_template.soletenant-tmpl.self_link}" } From c5837bc3295a9f60834dd35afc51443a6f4b63b6 Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Tue, 30 Apr 2019 17:31:11 -0700 Subject: [PATCH 4/8] add back send_empty_value --- products/compute/api.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/products/compute/api.yaml b/products/compute/api.yaml index 68ef32518813..c5ffb2c7fcca 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -4890,6 +4890,7 @@ objects: description: | The total number of nodes in the node group. required: true + send_empty_value: true - !ruby/object:Api::Resource name: 'NodeTemplate' kind: 'compute#nodeTemplate' From a9327db8404244d0228cc70cfa056c02582ea94c Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Wed, 1 May 2019 10:10:11 -0700 Subject: [PATCH 5/8] switch sizes in tests --- templates/terraform/examples/node_group_basic.tf.erb | 2 +- .../terraform/tests/resource_compute_node_group_test.go.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/terraform/examples/node_group_basic.tf.erb b/templates/terraform/examples/node_group_basic.tf.erb index 781df439f2f4..fc303a227944 100644 --- a/templates/terraform/examples/node_group_basic.tf.erb +++ b/templates/terraform/examples/node_group_basic.tf.erb @@ -13,6 +13,6 @@ resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" { zone = "us-central1-a" description = "example google_compute_node_group for Terraform Google Provider" - size = 0 + size = 1 node_template = "${google_compute_node_template.soletenant-tmpl.self_link}" } diff --git a/third_party/terraform/tests/resource_compute_node_group_test.go.erb b/third_party/terraform/tests/resource_compute_node_group_test.go.erb index 364ada8efb69..db7b12fe6e1a 100644 --- a/third_party/terraform/tests/resource_compute_node_group_test.go.erb +++ b/third_party/terraform/tests/resource_compute_node_group_test.go.erb @@ -109,7 +109,7 @@ resource "google_compute_node_group" "nodes" { zone = "us-central1-a" description = "example google_compute_node_group for Terraform Google Provider" - size = 1 + size = 0 node_template = "${google_compute_node_template.%s.self_link}" } `, tmplPrefix, tmplPrefix, groupName, tmplToUse) From 3bd11fb3ef0e880da1d511f71cc4007a6b885bf2 Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Wed, 1 May 2019 10:53:53 -0700 Subject: [PATCH 6/8] make replaceVars use getOkExists so zero-values are still set in url --- third_party/terraform/utils/transport.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/terraform/utils/transport.go b/third_party/terraform/utils/transport.go index e06e2496f2f6..dc847552f749 100644 --- a/third_party/terraform/utils/transport.go +++ b/third_party/terraform/utils/transport.go @@ -164,7 +164,7 @@ func buildReplacementFunc(re *regexp.Regexp, d TerraformResourceData, config *Co if m == "zone" { return zone } - v, ok := d.GetOk(m) + v, ok := d.GetOkExists(m) if ok { return fmt.Sprintf("%v", v) } From 1a2ebe4e5b27e7c66473d7933a4ed46219f0d09a Mon Sep 17 00:00:00 2001 From: Emily Ye Date: Wed, 1 May 2019 12:57:35 -0700 Subject: [PATCH 7/8] fix cai test --- third_party/validator/cai_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/third_party/validator/cai_test.go b/third_party/validator/cai_test.go index cc41289d3309..0a63013ffc23 100644 --- a/third_party/validator/cai_test.go +++ b/third_party/validator/cai_test.go @@ -70,6 +70,11 @@ type mockTerraformResourceData struct { TerraformResourceData } +func (d *mockTerraformResourceData) GetOkExists(k string) (interface{}, bool) { + v, ok := d.m[k] + return v, ok +} + func (d *mockTerraformResourceData) GetOk(k string) (interface{}, bool) { v, ok := d.m[k] return v, ok From b19f004945e3b9687696701091ed4eed80be57c4 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Wed, 1 May 2019 21:58:44 +0000 Subject: [PATCH 8/8] Update tracked submodules -> HEAD on Wed May 1 21:58:44 UTC 2019 Tracked submodules are build/terraform-beta build/terraform-mapper build/terraform build/ansible build/inspec. --- build/terraform | 2 +- build/terraform-beta | 2 +- build/terraform-mapper | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/terraform b/build/terraform index efc0e61a8ea9..78ef2f545bb1 160000 --- a/build/terraform +++ b/build/terraform @@ -1 +1 @@ -Subproject commit efc0e61a8ea912a4be3b8a7350de6b20aa836c19 +Subproject commit 78ef2f545bb11a902e887ece4501a44acf6a396f diff --git a/build/terraform-beta b/build/terraform-beta index 01bf20dfd3c9..8d3a644c9a4e 160000 --- a/build/terraform-beta +++ b/build/terraform-beta @@ -1 +1 @@ -Subproject commit 01bf20dfd3c907df282da4c6e258b08a3fad1286 +Subproject commit 8d3a644c9a4e709b7dba301e6fecc8a8aca5fa44 diff --git a/build/terraform-mapper b/build/terraform-mapper index 9657ade58a56..3ec7f45a44fc 160000 --- a/build/terraform-mapper +++ b/build/terraform-mapper @@ -1 +1 @@ -Subproject commit 9657ade58a5605159ec98d86ce963c90fba2101e +Subproject commit 3ec7f45a44fc865698fefd2390b46d4dc86ec1dd