Skip to content
Open
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
8 changes: 8 additions & 0 deletions mmv1/products/vmwareengine/Network.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
org_id: 'ORG_ID'
billing_account: 'BILLING_ACCT'
external_providers: ["random", "time"]
# update tests will take care of create and update. Legacy network needs to be created on an isolated project.

Check warning on line 65 in mmv1/products/vmwareengine/Network.yaml

View workflow job for this annotation

GitHub Actions / lint-yaml

65:2 [comments-indentation] comment not indented like content
exclude_test: true
parameters:
- name: 'location'
Expand Down Expand Up @@ -152,3 +152,11 @@
Checksum that may be sent on update and delete requests to ensure that the user-provided value is up to date befor
The server computes checksums based on the value of other fields in the request.
output: true
- name: 'tags'
type: KeyValuePairs
description: |
A map of resource manager tags.
Resource manager tag keys and values have the same definition as resource manager tags.
Keys must be in the format tagKeys/{tag_key_id}, and values are in the format tagValues/{tag_value_id}.
immutable: true
ignore_read: true
8 changes: 8 additions & 0 deletions mmv1/products/vmwareengine/NetworkPeering.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,11 @@ properties:
The canonical name of the VMware Engine network in the form:
projects/{project_number}/locations/{location}/vmwareEngineNetworks/{vmwareEngineNetworkId}
output: true
- name: 'tags'
type: KeyValuePairs
description: |
A map of resource manager tags.
Resource manager tag keys and values have the same definition as resource manager tags.
Keys must be in the format tagKeys/{tag_key_id}, and values are in the format tagValues/{tag_value_id}.
immutable: true
ignore_read: true
8 changes: 8 additions & 0 deletions mmv1/products/vmwareengine/NetworkPolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,11 @@ properties:
- 'UNPROVISIONED'
- 'RECONCILING'
- 'ACTIVE'
- name: 'tags'
type: KeyValuePairs
description: |
A map of resource manager tags.
Resource manager tag keys and values have the same definition as resource manager tags.
Keys must be in the format tagKeys/{tag_key_id}, and values are in the format tagValues/{tag_value_id}.
immutable: true
ignore_read: true
8 changes: 8 additions & 0 deletions mmv1/products/vmwareengine/PrivateCloud.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,11 @@ properties:
- 'STANDARD'
- 'TIME_LIMITED'
- 'STRETCHED'
- name: 'tags'
type: KeyValuePairs
description: |
A map of resource manager tags.
Resource manager tag keys and values have the same definition as resource manager tags.
Keys must be in the format tagKeys/{tag_key_id}, and values are in the format tagValues/{tag_value_id}.
immutable: true
ignore_read: true
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package vmwareengine_test

import (
"os"
"fmt"
"net/url"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
"github.com/hashicorp/terraform-plugin-testing/terraform"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
"strings"
)

func TestAccVmwareengineNetworkPeering_update(t *testing.T) {
Expand Down Expand Up @@ -84,3 +89,174 @@ data "google_vmwareengine_network_peering" "ds" {
}
`, context)
}

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

org := envvar.GetTestOrgFromEnv(t)
tagKey := acctest.BootstrapSharedTestOrganizationTagKey(t, "vennp-tagkey", map[string]interface{}{})
tagValue := acctest.BootstrapSharedTestOrganizationTagValue(t, "vennp-tagvalue", tagKey)

venSuffix1 := acctest.RandString(t, 10)
venSuffix2 := acctest.RandString(t, 10)

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"org": org,
"tagKey": tagKey,
"tagValue": tagValue,
"ven_suffix1": venSuffix1,
"ven_suffix2": venSuffix2,
"ven_name1": "tf-test-ven-" + venSuffix1,
"ven_name2": "tf-test-ven-" + venSuffix2,
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckVmwareengineNetworkPeeringDestroyProducer(t), // Assuming this exists
Steps: []resource.TestStep{
{
Config: testAccVmwareengineNetworkPeeringTags(context),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("google_vmwareengine_network_peering.default", "tags.%"),
testAccCheckVmwareengineNetworkPeeringHasTagBindings(t),
),
},
{
ResourceName: "google_vmwareengine_network_peering.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name", "vmware_engine_network", "peer_network", "tags"},
},
},
})
}

func testAccVmwareengineNetworkPeeringTags(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vmwareengine_network" "ven1" {
name = "%{ven_name1}"
location = "global"
type = "STANDARD"
description = "Terraform test network 1 for peering"
}

resource "google_vmwareengine_network" "ven2" {
name = "%{ven_name2}"
location = "global"
type = "STANDARD"
description = "Terraform test network 2 for peering"
}

resource "google_vmwareengine_network_peering" "default" {
name = "tf-test-ven-peering-%{random_suffix}"
vmware_engine_network = google_vmwareengine_network.ven1.id
peer_network = google_vmwareengine_network.ven2.id
peer_network_type = "VMWARE_ENGINE_NETWORK"
# description = "Optional description"

tags = {
"%{org}/%{tagKey}" = "%{tagValue}"
}
}
`, context)
}

func testAccCheckVmwareengineNetworkPeeringHasTagBindings(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
if rs.Type != "google_vmwareengine_network_peering" {
continue
}
if strings.HasPrefix(name, "data.") {
continue
}

config := acctest.GoogleProviderConfig(t)

// 1. Get the configured tag key and value from the state.
var configuredTagValueNamespacedName string
for key, val := range rs.Primary.Attributes {
if strings.HasPrefix(key, "tags.") && key != "tags.#" {
tagKeyNamespacedName := strings.TrimPrefix(key, "tags.")
tagValueShortName := val
if tagValueShortName != "" {
configuredTagValueNamespacedName = fmt.Sprintf("%s/%s", tagKeyNamespacedName, tagValueShortName)
break
}
}
}

if configuredTagValueNamespacedName == "" {
return fmt.Errorf("could not find a configured tag value in the state for resource %s", rs.Primary.ID)
}
if strings.Contains(configuredTagValueNamespacedName, "%{") {
return fmt.Errorf("tag namespaced name contains unsubstituted variables: %q", configuredTagValueNamespacedName)
}

// 2. Describe the tag value to get its full resource name.
safeNamespacedName := url.QueryEscape(configuredTagValueNamespacedName)
describeTagValueURL := fmt.Sprintf("https://cloudresourcemanager.googleapis.com/v3/tagValues/namespaced?name=%s", safeNamespacedName)

respDescribe, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
RawURL: describeTagValueURL,
UserAgent: config.UserAgent,
})
if err != nil {
return fmt.Errorf("error describing tag value %q: %v", configuredTagValueNamespacedName, err)
}
fullTagValueName, ok := respDescribe["name"].(string)
if !ok || fullTagValueName == "" {
return fmt.Errorf("tag value name not found for %q: %v", configuredTagValueNamespacedName, respDescribe)
}

// 3. Get the tag bindings from the VMware Engine Network Peering.
// ID format: projects/{project}/locations/{location}/networkPeerings/{networkPeeringId}
// Network Peerings are global for Vmware Engine
parentURL := fmt.Sprintf("//vmwareengine.googleapis.com/%s", rs.Primary.ID)
listBindingsURL := fmt.Sprintf("https://cloudresourcemanager.googleapis.com/v3/tagBindings?parent=%s", url.QueryEscape(parentURL))

resp, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
RawURL: listBindingsURL,
UserAgent: config.UserAgent,
})
if err != nil {
return fmt.Errorf("error calling TagBindings API for %s: %v", parentURL, err)
}

tagBindingsVal, exists := resp["tagBindings"]
if !exists {
tagBindingsVal = []interface{}{}
}
tagBindings, ok := tagBindingsVal.([]interface{})
if !ok {
return fmt.Errorf("'tagBindings' is not a slice for %s: %v", rs.Primary.ID, resp)
}

// 4. Perform the comparison.
foundMatch := false
for _, binding := range tagBindings {
bindingMap, ok := binding.(map[string]interface{})
if !ok {
continue
}
if bindingMap["tagValue"] == fullTagValueName {
foundMatch = true
break
}
}

if !foundMatch {
return fmt.Errorf("expected tag value %s (from %q) not found in bindings for %s. Bindings: %v", fullTagValueName, configuredTagValueNamespacedName, rs.Primary.ID, tagBindings)
}
t.Logf("Successfully found matching tag binding for %s with tagValue %s", rs.Primary.ID, fullTagValueName)
}
return nil
}
}

Loading
Loading