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

Share settings for sole-tenant node groups. #13522

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
3 changes: 3 additions & 0 deletions .changelog/7059.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: added `share_settings` field to the `google_compute_node_group` resource.
```
146 changes: 146 additions & 0 deletions google/resource_compute_node_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,46 @@ than or equal to max-nodes. The default value is 0.`,
ForceNew: true,
Description: `Name of the resource.`,
},
"share_settings": {
Type: schema.TypeList,
Computed: true,
Optional: true,
ForceNew: true,
Description: `Share settings for the node group.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"share_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateEnum([]string{"ORGANIZATION", "SPECIFIC_PROJECTS", "LOCAL"}),
Description: `Node group sharing type. Possible values: ["ORGANIZATION", "SPECIFIC_PROJECTS", "LOCAL"]`,
},
"project_map": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Description: `A map of project id and project config. This is only valid when shareType's value is SPECIFIC_PROJECTS.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The project id/number should be the same as the key of this project config in the project map.`,
},
},
},
},
},
},
},
"size": {
Type: schema.TypeInt,
Computed: true,
Expand Down Expand Up @@ -219,6 +259,12 @@ func resourceComputeNodeGroupCreate(d *schema.ResourceData, meta interface{}) er
} else if v, ok := d.GetOkExists("autoscaling_policy"); !isEmptyValue(reflect.ValueOf(autoscalingPolicyProp)) && (ok || !reflect.DeepEqual(v, autoscalingPolicyProp)) {
obj["autoscalingPolicy"] = autoscalingPolicyProp
}
shareSettingsProp, err := expandComputeNodeGroupShareSettings(d.Get("share_settings"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("share_settings"); !isEmptyValue(reflect.ValueOf(shareSettingsProp)) && (ok || !reflect.DeepEqual(v, shareSettingsProp)) {
obj["shareSettings"] = shareSettingsProp
}
zoneProp, err := expandComputeNodeGroupZone(d.Get("zone"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -338,6 +384,9 @@ func resourceComputeNodeGroupRead(d *schema.ResourceData, meta interface{}) erro
if err := d.Set("autoscaling_policy", flattenComputeNodeGroupAutoscalingPolicy(res["autoscalingPolicy"], d, config)); err != nil {
return fmt.Errorf("Error reading NodeGroup: %s", err)
}
if err := d.Set("share_settings", flattenComputeNodeGroupShareSettings(res["shareSettings"], d, config)); err != nil {
return fmt.Errorf("Error reading NodeGroup: %s", err)
}
if err := d.Set("zone", flattenComputeNodeGroupZone(res["zone"], d, config)); err != nil {
return fmt.Errorf("Error reading NodeGroup: %s", err)
}
Expand Down Expand Up @@ -583,6 +632,44 @@ func flattenComputeNodeGroupAutoscalingPolicyMaxNodes(v interface{}, d *schema.R
return v // let terraform core handle it otherwise
}

func flattenComputeNodeGroupShareSettings(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["share_type"] =
flattenComputeNodeGroupShareSettingsShareType(original["shareType"], d, config)
transformed["project_map"] =
flattenComputeNodeGroupShareSettingsProjectMap(original["projectMap"], d, config)
return []interface{}{transformed}
}
func flattenComputeNodeGroupShareSettingsShareType(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeNodeGroupShareSettingsProjectMap(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
}
l := v.(map[string]interface{})
transformed := make([]interface{}, 0, len(l))
for k, raw := range l {
original := raw.(map[string]interface{})
transformed = append(transformed, map[string]interface{}{
"id": k,
"project_id": flattenComputeNodeGroupShareSettingsProjectMapProjectId(original["projectId"], d, config),
})
}
return transformed
}
func flattenComputeNodeGroupShareSettingsProjectMapProjectId(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenComputeNodeGroupZone(v interface{}, d *schema.ResourceData, config *Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -682,6 +769,65 @@ func expandComputeNodeGroupAutoscalingPolicyMaxNodes(v interface{}, d TerraformR
return v, nil
}

func expandComputeNodeGroupShareSettings(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedShareType, err := expandComputeNodeGroupShareSettingsShareType(original["share_type"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedShareType); val.IsValid() && !isEmptyValue(val) {
transformed["shareType"] = transformedShareType
}

transformedProjectMap, err := expandComputeNodeGroupShareSettingsProjectMap(original["project_map"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedProjectMap); val.IsValid() && !isEmptyValue(val) {
transformed["projectMap"] = transformedProjectMap
}

return transformed, nil
}

func expandComputeNodeGroupShareSettingsShareType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandComputeNodeGroupShareSettingsProjectMap(v interface{}, d TerraformResourceData, config *Config) (map[string]interface{}, error) {
if v == nil {
return map[string]interface{}{}, nil
}
m := make(map[string]interface{})
for _, raw := range v.(*schema.Set).List() {
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedProjectId, err := expandComputeNodeGroupShareSettingsProjectMapProjectId(original["project_id"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedProjectId); val.IsValid() && !isEmptyValue(val) {
transformed["projectId"] = transformedProjectId
}

transformedId, err := expandString(original["id"], d, config)
if err != nil {
return nil, err
}
m[transformedId] = transformed
}
return m, nil
}

func expandComputeNodeGroupShareSettingsProjectMapProjectId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandComputeNodeGroupZone(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("zones", v.(string), "project", d, config, true)
if err != nil {
Expand Down
59 changes: 59 additions & 0 deletions google/resource_compute_node_group_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,65 @@ resource "google_compute_node_group" "nodes" {
`, context)
}

func TestAccComputeNodeGroup_nodeGroupShareSettingsExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_id": getTestOrgFromEnv(t),
"random_suffix": randString(t, 10),
}

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeNodeGroupDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeNodeGroup_nodeGroupShareSettingsExample(context),
},
{
ResourceName: "google_compute_node_group.nodes",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"node_template", "initial_size", "zone"},
},
},
})
}

func testAccComputeNodeGroup_nodeGroupShareSettingsExample(context map[string]interface{}) string {
return Nprintf(`
resource "google_project" "guest_project" {
project_id = "tf-test-project-id%{random_suffix}"
name = "tf-test-project-name%{random_suffix}"
org_id = "%{org_id}"
}

resource "google_compute_node_template" "soletenant-tmpl" {
name = "tf-test-soletenant-tmpl%{random_suffix}"
region = "us-central1"
node_type = "n1-node-96-624"
}

resource "google_compute_node_group" "nodes" {
name = "tf-test-soletenant-group%{random_suffix}"
zone = "us-central1-f"
description = "example google_compute_node_group for Terraform Google Provider"

size = 1
node_template = google_compute_node_template.soletenant-tmpl.id

share_settings {
share_type = "SPECIFIC_PROJECTS"
project_map {
id = google_project.guest_project.project_id
project_id = google_project.guest_project.project_id
}
}
}
`, context)
}

func testAccCheckComputeNodeGroupDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
Expand Down
59 changes: 59 additions & 0 deletions website/docs/r/compute_node_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,39 @@ resource "google_compute_node_group" "nodes" {
}
}
```
## Example Usage - Node Group Share Settings


```hcl
resource "google_project" "guest_project" {
project_id = "project-id"
name = "project-name"
org_id = "123456789"
}

resource "google_compute_node_template" "soletenant-tmpl" {
name = "soletenant-tmpl"
region = "us-central1"
node_type = "n1-node-96-624"
}

resource "google_compute_node_group" "nodes" {
name = "soletenant-group"
zone = "us-central1-f"
description = "example google_compute_node_group for Terraform Google Provider"

size = 1
node_template = google_compute_node_template.soletenant-tmpl.id

share_settings {
share_type = "SPECIFIC_PROJECTS"
project_map {
id = google_project.guest_project.project_id
project_id = google_project.guest_project.project_id
}
}
}
```

## Argument Reference

Expand Down Expand Up @@ -135,6 +168,11 @@ The following arguments are supported:
group autoscaler to automatically manage the sizes of your node groups.
Structure is [documented below](#nested_autoscaling_policy).

* `share_settings` -
(Optional)
Share settings for the node group.
Structure is [documented below](#nested_share_settings).

* `zone` -
(Optional)
Zone where this node group is located
Expand Down Expand Up @@ -171,6 +209,27 @@ The following arguments are supported:
Maximum size of the node group. Set to a value less than or equal
to 100 and greater than or equal to min-nodes.

<a name="nested_share_settings"></a>The `share_settings` block supports:

* `share_type` -
(Required)
Node group sharing type.
Possible values are `ORGANIZATION`, `SPECIFIC_PROJECTS`, and `LOCAL`.

* `project_map` -
(Optional)
A map of project id and project config. This is only valid when shareType's value is SPECIFIC_PROJECTS.
Structure is [documented below](#nested_project_map).


<a name="nested_project_map"></a>The `project_map` block supports:

* `id` - (Required) The identifier for this object. Format specified above.

* `project_id` -
(Required)
The project id/number should be the same as the key of this project config in the project map.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:
Expand Down