Skip to content

Commit b4135cb

Browse files
authored
Fix a bug where for the update network endpoints are sending empty in… (#15581)
1 parent 367bba5 commit b4135cb

File tree

6 files changed

+199
-6
lines changed

6 files changed

+199
-6
lines changed

mmv1/products/compute/NetworkEndpoints.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,12 @@ properties:
113113
properties:
114114
- name: 'instance'
115115
type: ResourceRef
116+
default_from_api: true
116117
description: |
117118
The name for a specific VM instance that the IP address belongs to.
118119
This is required for network endpoints of type GCE_VM_IP_PORT.
119120
The instance must be in the same zone as the network endpoint group.
120-
custom_expand: 'templates/terraform/custom_expand/resource_from_self_link.go.tmpl'
121+
custom_expand: 'templates/terraform/custom_expand/resource_from_self_link_nullable.go.tmpl'
121122
resource: 'Instance'
122123
imports: 'name'
123124
- name: 'port'

mmv1/products/compute/RegionNetworkEndpoint.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ examples:
7474
network_name: 'network'
7575
- name: 'region_network_endpoint_portmap'
7676
primary_resource_id: 'region_network_endpoint_portmap'
77-
min_version: 'beta'
7877
vars:
7978
network_name: 'network'
8079
subnetwork_name: 'subnetwork'
@@ -140,7 +139,6 @@ properties:
140139
type: Integer
141140
description: |
142141
Client destination port for the `GCE_VM_IP_PORTMAP` NEG.
143-
min_version: 'beta'
144142
custom_flatten: 'templates/terraform/custom_flatten/float64_to_int.go.tmpl'
145143
- name: 'instance'
146144
type: ResourceRef
@@ -149,4 +147,3 @@ properties:
149147
This is required for network endpoints of type GCE_VM_IP_PORTMAP.
150148
resource: 'Instance'
151149
imports: 'name'
152-
min_version: 'beta'

mmv1/templates/terraform/constants/network_endpoints.go.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ func NetworkEndpointsNetworkEndpointConvertToAny(endpoint NetworkEndpointsNetwor
3434
m := make(map[string]interface{})
3535
m["ip_address"] = endpoint.IPAddress
3636
m["port"] = endpoint.Port
37-
m["instance"] = endpoint.Instance
37+
if endpoint.Instance != "" {
38+
m["instance"] = endpoint.Instance
39+
}
3840
return m
3941
}
4042

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
func expand{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
2+
if tpgresource.IsEmptyValue(reflect.ValueOf(v.(string))) {
3+
return nil, nil
4+
}
5+
6+
return tpgresource.GetResourceNameFromSelfLink(v.(string)), nil
7+
}

mmv1/templates/terraform/pre_update/network_endpoints.go.tmpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ if err != nil {
5757
return err
5858
}
5959

60+
if len(lastPage) == 0 {
61+
return resourceComputeNetworkEndpointsRead(d, meta)
62+
}
63+
6064
obj = map[string]interface{}{
6165
"networkEndpoints": lastPage,
62-
}
66+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
package compute_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-testing/terraform"
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
"github.com/hashicorp/terraform-provider-google/google/envvar"
11+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
12+
)
13+
14+
func TestAccComputeNetworkEndpoints_recreateNetworkEndpointsBasic(t *testing.T) {
15+
// Multiple fine-grained resources
16+
acctest.SkipIfVcr(t)
17+
t.Parallel()
18+
19+
context := map[string]interface{}{
20+
"random_suffix": acctest.RandString(t, 10),
21+
}
22+
negId := fmt.Sprintf("projects/%s/zones/%s/networkEndpointGroups/tf-test-neg-%s",
23+
envvar.GetTestProjectFromEnv(), envvar.GetTestZoneFromEnv(), context["random_suffix"])
24+
25+
acctest.VcrTest(t, resource.TestCase{
26+
PreCheck: func() { acctest.AccTestPreCheck(t) },
27+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
28+
Steps: []resource.TestStep{
29+
{
30+
// Create one endpoint
31+
Config: testAccComputeNetworkEndpoints_networkEndpointGroupOnly(context),
32+
},
33+
{
34+
ResourceName: "google_compute_network_endpoint_group.external_group",
35+
ImportState: true,
36+
ImportStateVerify: true,
37+
},
38+
{
39+
// Create single endpoint
40+
Config: testAccComputeNetworkEndpoints_networkEndpointsSingle(context),
41+
},
42+
{
43+
ResourceName: "google_compute_network_endpoints.external_endpoints",
44+
ImportState: true,
45+
ImportStateVerify: true,
46+
},
47+
{
48+
// Add two new endpoints
49+
Config: testAccComputeNetworkEndpoints_networkEndpointsMultiple(context),
50+
},
51+
{
52+
ResourceName: "google_compute_network_endpoints.external_endpoints",
53+
ImportState: true,
54+
ImportStateVerify: true,
55+
},
56+
{
57+
// Remove two endpoints
58+
Config: testAccComputeNetworkEndpoints_networkEndpointsSingle(context),
59+
Check: resource.ComposeTestCheckFunc(
60+
testAccCheckComputeNetworkEndpointsWithPortsDestroyedCustom(t, negId, "8442"),
61+
testAccCheckComputeNetworkEndpointsWithPortsDestroyedCustom(t, negId, "8443"),
62+
),
63+
},
64+
{
65+
ResourceName: "google_compute_network_endpoints.external_endpoints",
66+
ImportState: true,
67+
ImportStateVerify: true,
68+
},
69+
{
70+
// Delete all endpoints
71+
Config: testAccComputeNetworkEndpoints_networkEndpointGroupOnly(context),
72+
Check: resource.ComposeTestCheckFunc(
73+
testAccCheckComputeNetworkEndpointsWithPortsDestroyedCustom(t, negId, "8441"),
74+
),
75+
},
76+
},
77+
})
78+
}
79+
80+
func testAccComputeNetworkEndpoints_networkEndpointsSingle(context map[string]interface{}) string {
81+
return acctest.Nprintf(`
82+
resource "google_compute_network_endpoints" "external_endpoints" {
83+
network_endpoint_group = google_compute_network_endpoint_group.external_group.id
84+
zone = google_compute_network_endpoint_group.external_group.zone
85+
86+
network_endpoints {
87+
ip_address = "8.8.8.8"
88+
port = 8441
89+
}
90+
}
91+
`, context) + testAccComputeNetworkEndpoints_networkEndpointGroupOnly(context)
92+
}
93+
94+
func testAccComputeNetworkEndpoints_networkEndpointsMultiple(context map[string]interface{}) string {
95+
return acctest.Nprintf(`
96+
resource "google_compute_network_endpoints" "external_endpoints" {
97+
network_endpoint_group = google_compute_network_endpoint_group.external_group.id
98+
zone = google_compute_network_endpoint_group.external_group.zone
99+
100+
network_endpoints {
101+
ip_address = "8.8.8.8"
102+
port = 8441
103+
}
104+
105+
network_endpoints {
106+
ip_address = "1.2.3.4"
107+
port = 8442
108+
}
109+
110+
network_endpoints {
111+
ip_address = "5.6.7.8"
112+
port = 8443
113+
}
114+
}
115+
`, context) + testAccComputeNetworkEndpoints_networkEndpointGroupOnly(context)
116+
}
117+
118+
func testAccComputeNetworkEndpoints_networkEndpointGroupOnly(context map[string]interface{}) string {
119+
return acctest.Nprintf(`
120+
resource "google_compute_network" "default" {
121+
name = "tf-test-neg-network-%{random_suffix}"
122+
}
123+
124+
resource "google_compute_network_endpoint_group" "external_group" {
125+
name = "tf-test-neg-%{random_suffix}"
126+
network = google_compute_network.default.self_link
127+
zone = "us-central1-a"
128+
network_endpoint_type = "NON_GCP_PRIVATE_IP_PORT"
129+
}
130+
`, context)
131+
}
132+
133+
// testAccCheckComputeNetworkEndpointsDestroyed makes sure the endpoint with
134+
// given Terraform resource name and previous information (obtained from Exists)
135+
// was destroyed properly.
136+
func testAccCheckComputeNetworkEndpointsWithPortsDestroyedCustom(t *testing.T, negId string, ports ...string) resource.TestCheckFunc {
137+
return func(s *terraform.State) error {
138+
foundPorts, err := testAccComputeNetworkEndpointsListEndpointPortsCustom(t, negId)
139+
if err != nil {
140+
return fmt.Errorf("unable to confirm endpoints with ports %+v was destroyed: %v", ports, err)
141+
}
142+
for _, p := range ports {
143+
if _, ok := foundPorts[p]; ok {
144+
return fmt.Errorf("network endpoint with port %s still exists", p)
145+
}
146+
}
147+
148+
return nil
149+
}
150+
}
151+
152+
func testAccComputeNetworkEndpointsListEndpointPortsCustom(t *testing.T, negId string) (map[string]struct{}, error) {
153+
config := acctest.GoogleProviderConfig(t)
154+
155+
url := fmt.Sprintf("https://www.googleapis.com/compute/v1/%s/listNetworkEndpoints", negId)
156+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
157+
Config: config,
158+
Method: "POST",
159+
RawURL: url,
160+
UserAgent: config.UserAgent,
161+
})
162+
if err != nil {
163+
return nil, err
164+
}
165+
166+
v, ok := res["items"]
167+
if !ok || v == nil {
168+
return nil, nil
169+
}
170+
items := v.([]interface{})
171+
ports := make(map[string]struct{})
172+
for _, item := range items {
173+
endptWithHealth := item.(map[string]interface{})
174+
v, ok := endptWithHealth["networkEndpoint"]
175+
if !ok || v == nil {
176+
continue
177+
}
178+
endpt := v.(map[string]interface{})
179+
ports[fmt.Sprintf("%v", endpt["port"])] = struct{}{}
180+
}
181+
return ports, nil
182+
}

0 commit comments

Comments
 (0)