Skip to content

Commit ea2fed8

Browse files
Backfill support for user_project_override and billing_project for google_service_networking_connection (#4995) (#3455)
* add project overrides to service networking Co-authored-by: upodroid <[email protected]> * add billing_project overrides * add override to docs Signed-off-by: Modular Magician <[email protected]>
1 parent c29fc4f commit ea2fed8

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

.changelog/4995.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
servicenetworking: added support for `user_project_override` and `billing_project ` to `google_service_networking_connection`
3+
```

google-beta/resource_service_networking_connection.go

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ func resourceServiceNetworkingConnectionCreate(d *schema.ResourceData, meta inte
8383
ReservedPeeringRanges: convertStringArr(d.Get("reserved_peering_ranges").([]interface{})),
8484
}
8585

86+
networkFieldValue, err := ParseNetworkFieldValue(network, d, config)
87+
if err != nil {
88+
return errwrap.Wrapf("Failed to retrieve network field value, err: {{err}}", err)
89+
}
90+
project := networkFieldValue.Project
91+
8692
parentService := formatParentService(d.Get("service").(string))
8793
// We use Patch instead of Create, because we're getting
8894
// "Error waiting for Create Service Networking Connection:
@@ -98,12 +104,22 @@ func resourceServiceNetworkingConnectionCreate(d *schema.ResourceData, meta inte
98104
// The API docs don't specify that you can do connections/-,
99105
// but that's what gcloud does, and it's easier than grabbing
100106
// the connection name.
101-
op, err := config.NewServiceNetworkingClient(userAgent).Services.Connections.Patch(parentService+"/connections/-", connection).UpdateMask("reservedPeeringRanges").Force(true).Do()
107+
108+
// err == nil indicates that the billing_project value was found
109+
if bp, err := getBillingProject(d, config); err == nil {
110+
project = bp
111+
}
112+
113+
createCall := config.NewServiceNetworkingClient(userAgent).Services.Connections.Patch(parentService+"/connections/-", connection).UpdateMask("reservedPeeringRanges").Force(true)
114+
if config.UserProjectOverride {
115+
createCall.Header().Add("X-Goog-User-Project", project)
116+
}
117+
op, err := createCall.Do()
102118
if err != nil {
103119
return err
104120
}
105121

106-
if err := serviceNetworkingOperationWaitTime(config, op, "Create Service Networking Connection", userAgent, d.Timeout(schema.TimeoutCreate)); err != nil {
122+
if err := serviceNetworkingOperationWaitTime(config, op, "Create Service Networking Connection", userAgent, project, d.Timeout(schema.TimeoutCreate)); err != nil {
107123
return err
108124
}
109125

@@ -133,9 +149,24 @@ func resourceServiceNetworkingConnectionRead(d *schema.ResourceData, meta interf
133149
return errwrap.Wrapf("Failed to find Service Networking Connection, err: {{err}}", err)
134150
}
135151

152+
network := d.Get("network").(string)
153+
networkFieldValue, err := ParseNetworkFieldValue(network, d, config)
154+
if err != nil {
155+
return errwrap.Wrapf("Failed to retrieve network field value, err: {{err}}", err)
156+
}
157+
project := networkFieldValue.Project
158+
159+
// err == nil indicates that the billing_project value was found
160+
if bp, err := getBillingProject(d, config); err == nil {
161+
project = bp
162+
}
163+
136164
parentService := formatParentService(connectionId.Service)
137-
response, err := config.NewServiceNetworkingClient(userAgent).Services.Connections.List(parentService).
138-
Network(serviceNetworkingNetworkName).Do()
165+
readCall := config.NewServiceNetworkingClient(userAgent).Services.Connections.List(parentService).Network(serviceNetworkingNetworkName)
166+
if config.UserProjectOverride {
167+
readCall.Header().Add("X-Goog-User-Project", project)
168+
}
169+
response, err := readCall.Do()
139170
if err != nil {
140171
return err
141172
}
@@ -195,13 +226,29 @@ func resourceServiceNetworkingConnectionUpdate(d *schema.ResourceData, meta inte
195226
ReservedPeeringRanges: convertStringArr(d.Get("reserved_peering_ranges").([]interface{})),
196227
}
197228

229+
networkFieldValue, err := ParseNetworkFieldValue(network, d, config)
230+
if err != nil {
231+
return errwrap.Wrapf("Failed to retrieve network field value, err: {{err}}", err)
232+
}
233+
project := networkFieldValue.Project
234+
198235
// The API docs don't specify that you can do connections/-, but that's what gcloud does,
199236
// and it's easier than grabbing the connection name.
200-
op, err := config.NewServiceNetworkingClient(userAgent).Services.Connections.Patch(parentService+"/connections/-", connection).UpdateMask("reservedPeeringRanges").Force(true).Do()
237+
238+
// err == nil indicates that the billing_project value was found
239+
if bp, err := getBillingProject(d, config); err == nil {
240+
project = bp
241+
}
242+
243+
patchCall := config.NewServiceNetworkingClient(userAgent).Services.Connections.Patch(parentService+"/connections/-", connection).UpdateMask("reservedPeeringRanges").Force(true)
244+
if config.UserProjectOverride {
245+
patchCall.Header().Add("X-Goog-User-Project", project)
246+
}
247+
op, err := patchCall.Do()
201248
if err != nil {
202249
return err
203250
}
204-
if err := serviceNetworkingOperationWaitTime(config, op, "Update Service Networking Connection", userAgent, d.Timeout(schema.TimeoutUpdate)); err != nil {
251+
if err := serviceNetworkingOperationWaitTime(config, op, "Update Service Networking Connection", userAgent, project, d.Timeout(schema.TimeoutUpdate)); err != nil {
205252
return err
206253
}
207254
}
@@ -322,7 +369,17 @@ func retrieveServiceNetworkingNetworkName(d *schema.ResourceData, config *Config
322369
return "", fmt.Errorf("Could not determine project")
323370
}
324371
log.Printf("[DEBUG] Retrieving project number by doing a GET with the project id, as required by service networking")
325-
project, err := config.NewResourceManagerClient(userAgent).Projects.Get(pid).Do()
372+
// err == nil indicates that the billing_project value was found
373+
billingProject := pid
374+
if bp, err := getBillingProject(d, config); err == nil {
375+
billingProject = bp
376+
}
377+
378+
getProjectCall := config.NewResourceManagerClient(userAgent).Projects.Get(pid)
379+
if config.UserProjectOverride {
380+
getProjectCall.Header().Add("X-Goog-User-Project", billingProject)
381+
}
382+
project, err := getProjectCall.Do()
326383
if err != nil {
327384
// note: returning a wrapped error is part of this method's contract!
328385
// https://blog.golang.org/go1.13-errors

google-beta/resource_service_networking_connection_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ func testServiceNetworkingConnectionDestroy(t *testing.T, parent, network string
7171
config := googleProviderConfig(t)
7272
parentService := "services/" + parent
7373
networkName := fmt.Sprintf("projects/%s/global/networks/%s", getTestProjectFromEnv(), network)
74-
75-
response, err := config.NewServiceNetworkingClient(config.userAgent).Services.Connections.List(parentService).
76-
Network(networkName).Do()
74+
listCall := config.NewServiceNetworkingClient(config.userAgent).Services.Connections.List(parentService).Network(networkName)
75+
if config.UserProjectOverride {
76+
listCall.Header().Add("X-Goog-User-Project", getTestProjectFromEnv())
77+
}
78+
response, err := listCall.Do()
7779
if err != nil {
7880
return err
7981
}

google-beta/service_networking_operation.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,25 @@ import (
77
)
88

99
type ServiceNetworkingOperationWaiter struct {
10-
Service *servicenetworking.APIService
10+
Service *servicenetworking.APIService
11+
Project string
12+
UserProjectOverride bool
1113
CommonOperationWaiter
1214
}
1315

1416
func (w *ServiceNetworkingOperationWaiter) QueryOp() (interface{}, error) {
15-
return w.Service.Operations.Get(w.Op.Name).Do()
17+
opGetCall := w.Service.Operations.Get(w.Op.Name)
18+
if w.UserProjectOverride {
19+
opGetCall.Header().Add("X-Goog-User-Project", w.Project)
20+
}
21+
return opGetCall.Do()
1622
}
1723

18-
func serviceNetworkingOperationWaitTime(config *Config, op *servicenetworking.Operation, activity, userAgent string, timeout time.Duration) error {
24+
func serviceNetworkingOperationWaitTime(config *Config, op *servicenetworking.Operation, activity, userAgent, project string, timeout time.Duration) error {
1925
w := &ServiceNetworkingOperationWaiter{
20-
Service: config.NewServiceNetworkingClient(userAgent),
26+
Service: config.NewServiceNetworkingClient(userAgent),
27+
Project: project,
28+
UserProjectOverride: config.UserProjectOverride,
2129
}
2230

2331
if err := w.SetOp(op); err != nil {

website/docs/r/service_networking_connection.html.markdown

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ ServiceNetworkingConnection can be imported using any of these accepted formats
5656
* terraform import google_service_networking_connection.peering_connection {{peering-network}}:{{service}}
5757

5858
* terraform import google_service_networking_connection.peering_connection /projects/{{project}}/global/networks/{{peering-network}}:{{service}}
59+
60+
61+
## User Project Overrides
62+
63+
This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override).

0 commit comments

Comments
 (0)