@@ -36,6 +36,7 @@ func ResourceComputeGlobalAddress() *schema.Resource {
36
36
return & schema.Resource {
37
37
Create : resourceComputeGlobalAddressCreate ,
38
38
Read : resourceComputeGlobalAddressRead ,
39
+ Update : resourceComputeGlobalAddressUpdate ,
39
40
Delete : resourceComputeGlobalAddressDelete ,
40
41
41
42
Importer : & schema.ResourceImporter {
@@ -44,6 +45,7 @@ func ResourceComputeGlobalAddress() *schema.Resource {
44
45
45
46
Timeouts : & schema.ResourceTimeout {
46
47
Create : schema .DefaultTimeout (20 * time .Minute ),
48
+ Update : schema .DefaultTimeout (20 * time .Minute ),
47
49
Delete : schema .DefaultTimeout (20 * time .Minute ),
48
50
},
49
51
@@ -100,6 +102,16 @@ address or omitted to allow GCP to choose a valid one for you.`,
100
102
DiffSuppressFunc : tpgresource .EmptyOrDefaultStringSuppress ("IPV4" ),
101
103
Description : `The IP Version that will be used by this address. The default value is 'IPV4'. Possible values: ["IPV4", "IPV6"]` ,
102
104
},
105
+ "labels" : {
106
+ Type : schema .TypeMap ,
107
+ Optional : true ,
108
+ Description : `Labels to apply to this address. A list of key->value pairs.
109
+
110
+
111
+ **Note**: This field is non-authoritative, and will only manage the labels present in your configuration.
112
+ Please refer to the field 'effective_labels' for all of the labels present on the resource.` ,
113
+ Elem : & schema.Schema {Type : schema .TypeString },
114
+ },
103
115
"network" : {
104
116
Type : schema .TypeString ,
105
117
Optional : true ,
@@ -137,6 +149,19 @@ when purpose=PRIVATE_SERVICE_CONNECT`,
137
149
Computed : true ,
138
150
Description : `Creation timestamp in RFC3339 text format.` ,
139
151
},
152
+ "effective_labels" : {
153
+ Type : schema .TypeMap ,
154
+ Computed : true ,
155
+ Description : `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.` ,
156
+ Elem : & schema.Schema {Type : schema .TypeString },
157
+ },
158
+ "terraform_labels" : {
159
+ Type : schema .TypeMap ,
160
+ Computed : true ,
161
+ Description : `The combination of labels configured directly on the resource
162
+ and default labels configured on the provider.` ,
163
+ Elem : & schema.Schema {Type : schema .TypeString },
164
+ },
140
165
"project" : {
141
166
Type : schema .TypeString ,
142
167
Optional : true ,
@@ -208,6 +233,12 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
208
233
} else if v , ok := d .GetOkExists ("network" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (networkProp )) && (ok || ! reflect .DeepEqual (v , networkProp )) {
209
234
obj ["network" ] = networkProp
210
235
}
236
+ labelsProp , err := expandComputeGlobalAddressEffectiveLabels (d .Get ("effective_labels" ), d , config )
237
+ if err != nil {
238
+ return err
239
+ } else if v , ok := d .GetOkExists ("effective_labels" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (labelsProp )) && (ok || ! reflect .DeepEqual (v , labelsProp )) {
240
+ obj ["labels" ] = labelsProp
241
+ }
211
242
212
243
url , err := tpgresource .ReplaceVars (d , config , "{{ComputeBasePath}}projects/{{project}}/global/addresses" )
213
244
if err != nil {
@@ -265,6 +296,66 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{}
265
296
return fmt .Errorf ("Error waiting to create GlobalAddress: %s" , err )
266
297
}
267
298
299
+ if v , ok := d .GetOkExists ("effective_labels" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , labelsProp )) {
300
+ labels := d .Get ("labels" )
301
+ terraformLables := d .Get ("terraform_labels" )
302
+
303
+ // Labels cannot be set in a create. We'll have to set them here.
304
+ err = resourceComputeGlobalAddressRead (d , meta )
305
+ if err != nil {
306
+ return err
307
+ }
308
+
309
+ obj := make (map [string ]interface {})
310
+ // d.Get("effective_labels") will have been overridden by the Read call.
311
+ labelsProp , err := expandComputeGlobalAddressEffectiveLabels (v , d , config )
312
+ if err != nil {
313
+ return err
314
+ }
315
+ obj ["labels" ] = labelsProp
316
+ labelFingerprintProp := d .Get ("label_fingerprint" )
317
+ obj ["labelFingerprint" ] = labelFingerprintProp
318
+
319
+ url , err = tpgresource .ReplaceVars (d , config , "{{ComputeBasePath}}projects/{{project}}/global/addresses/{{name}}/setLabels" )
320
+ if err != nil {
321
+ return err
322
+ }
323
+ res , err = transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
324
+ Config : config ,
325
+ Method : "POST" ,
326
+ Project : project ,
327
+ RawURL : url ,
328
+ UserAgent : userAgent ,
329
+ Body : obj ,
330
+ })
331
+ if err != nil {
332
+ return fmt .Errorf ("Error adding labels to ComputeGlobalAddress %q: %s" , d .Id (), err )
333
+ }
334
+
335
+ err = ComputeOperationWaitTime (
336
+ config , res , project , "Updating ComputeGlobalAddress Labels" , userAgent ,
337
+ d .Timeout (schema .TimeoutUpdate ))
338
+
339
+ if err != nil {
340
+ return err
341
+ }
342
+
343
+ // Set back the labels field, as it is needed to decide the value of "labels" in the state in the read function.
344
+ if err := d .Set ("labels" , labels ); err != nil {
345
+ return fmt .Errorf ("Error setting back labels: %s" , err )
346
+ }
347
+
348
+ // Set back the terraform_labels field, as it is needed to decide the value of "terraform_labels" in the state in the read function.
349
+ if err := d .Set ("terraform_labels" , terraformLables ); err != nil {
350
+ return fmt .Errorf ("Error setting back terraform_labels: %s" , err )
351
+ }
352
+
353
+ // Set back the effective_labels field, as it is needed to decide the value of "effective_labels" in the state in the read function.
354
+ if err := d .Set ("effective_labels" , v ); err != nil {
355
+ return fmt .Errorf ("Error setting back effective_labels: %s" , err )
356
+ }
357
+ }
358
+
268
359
log .Printf ("[DEBUG] Finished creating GlobalAddress %q: %#v" , d .Id (), res )
269
360
270
361
return resourceComputeGlobalAddressRead (d , meta )
@@ -324,6 +415,9 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
324
415
if err := d .Set ("name" , flattenComputeGlobalAddressName (res ["name" ], d , config )); err != nil {
325
416
return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
326
417
}
418
+ if err := d .Set ("labels" , flattenComputeGlobalAddressLabels (res ["labels" ], d , config )); err != nil {
419
+ return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
420
+ }
327
421
if err := d .Set ("ip_version" , flattenComputeGlobalAddressIpVersion (res ["ipVersion" ], d , config )); err != nil {
328
422
return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
329
423
}
@@ -339,13 +433,87 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{})
339
433
if err := d .Set ("network" , flattenComputeGlobalAddressNetwork (res ["network" ], d , config )); err != nil {
340
434
return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
341
435
}
436
+ if err := d .Set ("terraform_labels" , flattenComputeGlobalAddressTerraformLabels (res ["labels" ], d , config )); err != nil {
437
+ return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
438
+ }
439
+ if err := d .Set ("effective_labels" , flattenComputeGlobalAddressEffectiveLabels (res ["labels" ], d , config )); err != nil {
440
+ return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
441
+ }
342
442
if err := d .Set ("self_link" , tpgresource .ConvertSelfLinkToV1 (res ["selfLink" ].(string ))); err != nil {
343
443
return fmt .Errorf ("Error reading GlobalAddress: %s" , err )
344
444
}
345
445
346
446
return nil
347
447
}
348
448
449
+ func resourceComputeGlobalAddressUpdate (d * schema.ResourceData , meta interface {}) error {
450
+ config := meta .(* transport_tpg.Config )
451
+ userAgent , err := tpgresource .GenerateUserAgentString (d , config .UserAgent )
452
+ if err != nil {
453
+ return err
454
+ }
455
+
456
+ billingProject := ""
457
+
458
+ project , err := tpgresource .GetProject (d , config )
459
+ if err != nil {
460
+ return fmt .Errorf ("Error fetching project for GlobalAddress: %s" , err )
461
+ }
462
+ billingProject = project
463
+
464
+ d .Partial (true )
465
+
466
+ if d .HasChange ("effective_labels" ) {
467
+ obj := make (map [string ]interface {})
468
+
469
+ labelsProp , err := expandComputeGlobalAddressEffectiveLabels (d .Get ("effective_labels" ), d , config )
470
+ if err != nil {
471
+ return err
472
+ } else if v , ok := d .GetOkExists ("effective_labels" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , labelsProp )) {
473
+ obj ["labels" ] = labelsProp
474
+ }
475
+
476
+ url , err := tpgresource .ReplaceVars (d , config , "{{ComputeBasePath}}projects/{{project}}/global/addresses/{{name}}/setLabels" )
477
+ if err != nil {
478
+ return err
479
+ }
480
+
481
+ headers := make (http.Header )
482
+
483
+ // err == nil indicates that the billing_project value was found
484
+ if bp , err := tpgresource .GetBillingProject (d , config ); err == nil {
485
+ billingProject = bp
486
+ }
487
+
488
+ res , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
489
+ Config : config ,
490
+ Method : "POST" ,
491
+ Project : billingProject ,
492
+ RawURL : url ,
493
+ UserAgent : userAgent ,
494
+ Body : obj ,
495
+ Timeout : d .Timeout (schema .TimeoutUpdate ),
496
+ Headers : headers ,
497
+ })
498
+ if err != nil {
499
+ return fmt .Errorf ("Error updating GlobalAddress %q: %s" , d .Id (), err )
500
+ } else {
501
+ log .Printf ("[DEBUG] Finished updating GlobalAddress %q: %#v" , d .Id (), res )
502
+ }
503
+
504
+ err = ComputeOperationWaitTime (
505
+ config , res , project , "Updating GlobalAddress" , userAgent ,
506
+ d .Timeout (schema .TimeoutUpdate ))
507
+ if err != nil {
508
+ return err
509
+ }
510
+ }
511
+
512
+ d .Partial (false )
513
+
514
+ return resourceComputeGlobalAddressRead (d , meta )
515
+ }
516
+
349
517
func resourceComputeGlobalAddressDelete (d * schema.ResourceData , meta interface {}) error {
350
518
config := meta .(* transport_tpg.Config )
351
519
userAgent , err := tpgresource .GenerateUserAgentString (d , config .UserAgent )
@@ -438,6 +606,21 @@ func flattenComputeGlobalAddressName(v interface{}, d *schema.ResourceData, conf
438
606
return v
439
607
}
440
608
609
+ func flattenComputeGlobalAddressLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
610
+ if v == nil {
611
+ return v
612
+ }
613
+
614
+ transformed := make (map [string ]interface {})
615
+ if l , ok := d .GetOkExists ("labels" ); ok {
616
+ for k := range l .(map [string ]interface {}) {
617
+ transformed [k ] = v .(map [string ]interface {})[k ]
618
+ }
619
+ }
620
+
621
+ return transformed
622
+ }
623
+
441
624
func flattenComputeGlobalAddressIpVersion (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
442
625
return v
443
626
}
@@ -474,6 +657,25 @@ func flattenComputeGlobalAddressNetwork(v interface{}, d *schema.ResourceData, c
474
657
return tpgresource .ConvertSelfLinkToV1 (v .(string ))
475
658
}
476
659
660
+ func flattenComputeGlobalAddressTerraformLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
661
+ if v == nil {
662
+ return v
663
+ }
664
+
665
+ transformed := make (map [string ]interface {})
666
+ if l , ok := d .GetOkExists ("terraform_labels" ); ok {
667
+ for k := range l .(map [string ]interface {}) {
668
+ transformed [k ] = v .(map [string ]interface {})[k ]
669
+ }
670
+ }
671
+
672
+ return transformed
673
+ }
674
+
675
+ func flattenComputeGlobalAddressEffectiveLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
676
+ return v
677
+ }
678
+
477
679
func expandComputeGlobalAddressAddress (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
478
680
return v , nil
479
681
}
@@ -509,3 +711,14 @@ func expandComputeGlobalAddressNetwork(v interface{}, d tpgresource.TerraformRes
509
711
}
510
712
return f .RelativeLink (), nil
511
713
}
714
+
715
+ func expandComputeGlobalAddressEffectiveLabels (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (map [string ]string , error ) {
716
+ if v == nil {
717
+ return map [string ]string {}, nil
718
+ }
719
+ m := make (map [string ]string )
720
+ for k , val := range v .(map [string ]interface {}) {
721
+ m [k ] = val .(string )
722
+ }
723
+ return m , nil
724
+ }
0 commit comments