Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add node groups (sole-tenant nodes) #1697

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/terraform
2 changes: 1 addition & 1 deletion build/terraform-beta
2 changes: 1 addition & 1 deletion build/terraform-mapper
4 changes: 4 additions & 0 deletions products/compute/ansible.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
70 changes: 69 additions & 1 deletion products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4823,6 +4823,74 @@ 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
send_empty_value: true
- !ruby/object:Api::Resource
name: 'NodeTemplate'
kind: 'compute#nodeTemplate'
Expand All @@ -4831,7 +4899,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:
Expand Down
2 changes: 2 additions & 0 deletions products/compute/inspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions products/compute/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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
Expand Down
18 changes: 18 additions & 0 deletions templates/terraform/examples/node_group_basic.tf.erb
Original file line number Diff line number Diff line change
@@ -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}"
}
116 changes: 116 additions & 0 deletions third_party/terraform/tests/resource_compute_node_group_test.go.erb
Original file line number Diff line number Diff line change
@@ -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 = 0
node_template = "${google_compute_node_template.%s.self_link}"
}
`, tmplPrefix, tmplPrefix, groupName, tmplToUse)
}
2 changes: 1 addition & 1 deletion third_party/terraform/utils/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
4 changes: 4 additions & 0 deletions third_party/terraform/website-compiled/google.erb
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@
<a href="/docs/providers/google/r/compute_interconnect_attachment.html">google_compute_interconnect_attachment</a>
</li>

<li<%%= sidebar_current("docs-google-compute-node-group") %>>
<a href="/docs/providers/google/r/compute_node_group.html">google_compute_node_group</a>
</li>

<li<%%= sidebar_current("docs-google-compute-node-template") %>>
<a href="/docs/providers/google/r/compute_node_template.html">google_compute_node_template</a>
</li>
Expand Down
5 changes: 5 additions & 0 deletions third_party/validator/cai_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down