Skip to content

Commit

Permalink
Add labels field to the GKEHub Scope resource and make it updatable (#…
Browse files Browse the repository at this point in the history
…8882) (#15801)

* Adding Terraform resources for Tenancy APIs in GKEHub

* Segregating MembershipBinding and MembershipRBACRoleBinding to keep things simpler in the review

* Fixing the docu URIs

* Adding TF support for Tenancy API for Membership Binding

* Adding dependent membership binding to the same commit chain

* Making Scope un-updatable and replacing hard coded project number with the one from test env

* Making Scope RRBAC updatable

* Making Namespace immutable

* Adding update test cases

* Removing all memberships field from Scope since it is no longer supported

* Removing all_memberships field for Scope from all test cases

* Adding labels field to the GKEHub Scope resource

* Fixing typo in the comment

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Sep 11, 2023
1 parent caffa8a commit 77fa016
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/8882.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
gkehub: added `labels` fields to `google_gke_hub_scope` resource
```
25 changes: 25 additions & 0 deletions google/services/gkehub2/iam_gke_hub_scope_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func testAccGKEHub2ScopeIamMember_basicGenerated(context map[string]interface{})
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
resource "google_gke_hub_scope_iam_member" "foo" {
Expand All @@ -145,6 +150,11 @@ func testAccGKEHub2ScopeIamPolicy_basicGenerated(context map[string]interface{})
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
data "google_iam_policy" "foo" {
Expand Down Expand Up @@ -174,6 +184,11 @@ func testAccGKEHub2ScopeIamPolicy_emptyBinding(context map[string]interface{}) s
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
data "google_iam_policy" "foo" {
Expand All @@ -191,6 +206,11 @@ func testAccGKEHub2ScopeIamBinding_basicGenerated(context map[string]interface{}
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
resource "google_gke_hub_scope_iam_binding" "foo" {
Expand All @@ -206,6 +226,11 @@ func testAccGKEHub2ScopeIamBinding_updateGenerated(context map[string]interface{
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
resource "google_gke_hub_scope_iam_binding" "foo" {
Expand Down
107 changes: 107 additions & 0 deletions google/services/gkehub2/resource_gke_hub_scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package gkehub2
import (
"fmt"
"log"
"reflect"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -32,6 +34,7 @@ func ResourceGKEHub2Scope() *schema.Resource {
return &schema.Resource{
Create: resourceGKEHub2ScopeCreate,
Read: resourceGKEHub2ScopeRead,
Update: resourceGKEHub2ScopeUpdate,
Delete: resourceGKEHub2ScopeDelete,

Importer: &schema.ResourceImporter{
Expand All @@ -40,6 +43,7 @@ func ResourceGKEHub2Scope() *schema.Resource {

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},

Expand All @@ -50,6 +54,12 @@ func ResourceGKEHub2Scope() *schema.Resource {
ForceNew: true,
Description: `The client-provided identifier of the scope.`,
},
"labels": {
Type: schema.TypeMap,
Optional: true,
Description: `Labels for this Scope.`,
Elem: &schema.Schema{Type: schema.TypeString},
},
"create_time": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -108,6 +118,12 @@ func resourceGKEHub2ScopeCreate(d *schema.ResourceData, meta interface{}) error
}

obj := make(map[string]interface{})
labelsProp, err := expandGKEHub2ScopeLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{GKEHub2BasePath}}projects/{{project}}/locations/global/scopes?scopeId={{scope_id}}")
if err != nil {
Expand Down Expand Up @@ -235,10 +251,86 @@ func resourceGKEHub2ScopeRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("state", flattenGKEHub2ScopeState(res["state"], d, config)); err != nil {
return fmt.Errorf("Error reading Scope: %s", err)
}
if err := d.Set("labels", flattenGKEHub2ScopeLabels(res["labels"], d, config)); err != nil {
return fmt.Errorf("Error reading Scope: %s", err)
}

return nil
}

func resourceGKEHub2ScopeUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

billingProject := ""

project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for Scope: %s", err)
}
billingProject = project

obj := make(map[string]interface{})
labelsProp, err := expandGKEHub2ScopeLabels(d.Get("labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{GKEHub2BasePath}}projects/{{project}}/locations/global/scopes/{{scope_id}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Updating Scope %q: %#v", d.Id(), obj)
updateMask := []string{}

if d.HasChange("labels") {
updateMask = append(updateMask, "labels")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}

// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "PATCH",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
})

if err != nil {
return fmt.Errorf("Error updating Scope %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating Scope %q: %#v", d.Id(), res)
}

err = GKEHub2OperationWaitTime(
config, res, project, "Updating Scope", userAgent,
d.Timeout(schema.TimeoutUpdate))

if err != nil {
return err
}

return resourceGKEHub2ScopeRead(d, meta)
}

func resourceGKEHub2ScopeDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
Expand Down Expand Up @@ -348,3 +440,18 @@ func flattenGKEHub2ScopeState(v interface{}, d *schema.ResourceData, config *tra
func flattenGKEHub2ScopeStateCode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenGKEHub2ScopeLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func expandGKEHub2ScopeLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) {
if v == nil {
return map[string]string{}, nil
}
m := make(map[string]string)
for k, val := range v.(map[string]interface{}) {
m[k] = val.(string)
}
return m, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ func testAccGKEHub2Scope_gkehubScopeBasicExample(context map[string]interface{})
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
`, context)
}
Expand Down
72 changes: 72 additions & 0 deletions google/services/gkehub2/resource_gke_hub_scope_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package gkehub2_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

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

context := map[string]interface{}{
"project": envvar.GetTestProjectFromEnv(),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccGKEHub2Scope_gkehubScopeBasicExample_basic(context),
},
{
ResourceName: "google_gke_hub_scope.scope",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"scope_id"},
},
{
Config: testAccGKEHub2Scope_gkehubScopeBasicExample_update(context),
},
{
ResourceName: "google_gke_hub_scope.scope",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"scope_id"},
},
},
})
}

func testAccGKEHub2Scope_gkehubScopeBasicExample_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
`, context)
}

func testAccGKEHub2Scope_gkehubScopeBasicExample_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
updated_keyb = "updated_valueb"
updated_keya = "updated_valuea"
updated_keyc = "updated_valuec"
}
}
`, context)
}
10 changes: 10 additions & 0 deletions website/docs/r/gke_hub_scope.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ To get more information about Scope, see:
```hcl
resource "google_gke_hub_scope" "scope" {
scope_id = "tf-test-scope%{random_suffix}"
labels = {
keyb = "valueb"
keya = "valuea"
keyc = "valuec"
}
}
```

Expand All @@ -50,6 +55,10 @@ The following arguments are supported:
- - -


* `labels` -
(Optional)
Labels for this Scope.

* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.

Expand Down Expand Up @@ -92,6 +101,7 @@ This resource provides the following
[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options:

- `create` - Default is 20 minutes.
- `update` - Default is 20 minutes.
- `delete` - Default is 20 minutes.

## Import
Expand Down

0 comments on commit 77fa016

Please sign in to comment.