@@ -37,6 +37,7 @@ func ResourceComputeHaVpnGateway() *schema.Resource {
3737 return & schema.Resource {
3838 Create : resourceComputeHaVpnGatewayCreate ,
3939 Read : resourceComputeHaVpnGatewayRead ,
40+ Update : resourceComputeHaVpnGatewayUpdate ,
4041 Delete : resourceComputeHaVpnGatewayDelete ,
4142
4243 Importer : & schema.ResourceImporter {
@@ -45,6 +46,7 @@ func ResourceComputeHaVpnGateway() *schema.Resource {
4546
4647 Timeouts : & schema.ResourceTimeout {
4748 Create : schema .DefaultTimeout (20 * time .Minute ),
49+ Update : schema .DefaultTimeout (20 * time .Minute ),
4850 Delete : schema .DefaultTimeout (20 * time .Minute ),
4951 },
5052
@@ -58,6 +60,7 @@ func ResourceComputeHaVpnGateway() *schema.Resource {
5860 },
5961 },
6062 CustomizeDiff : customdiff .All (
63+ tpgresource .SetLabelsDiff ,
6164 tpgresource .DefaultProviderProject ,
6265 ),
6366
@@ -96,6 +99,17 @@ character, which cannot be a dash.`,
9699 Description : `The IP family of the gateway IPs for the HA-VPN gateway interfaces. If not specified, IPV4 will be used. Default value: "IPV4" Possible values: ["IPV4", "IPV6"]` ,
97100 Default : "IPV4" ,
98101 },
102+ "labels" : {
103+ Type : schema .TypeMap ,
104+ Optional : true ,
105+ Description : `Labels for this resource. These can only be added or modified by the setLabels method.
106+ Each label key/value pair must comply with RFC1035. Label values may be empty.
107+
108+
109+ **Note**: This field is non-authoritative, and will only manage the labels present in your configuration.
110+ Please refer to the field 'effective_labels' for all of the labels present on the resource.` ,
111+ Elem : & schema.Schema {Type : schema .TypeString },
112+ },
99113 "region" : {
100114 Type : schema .TypeString ,
101115 Computed : true ,
@@ -148,6 +162,28 @@ Not currently available publicly.`,
148162 },
149163 },
150164 },
165+ "effective_labels" : {
166+ Type : schema .TypeMap ,
167+ Computed : true ,
168+ Description : `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.` ,
169+ Elem : & schema.Schema {Type : schema .TypeString },
170+ },
171+ "label_fingerprint" : {
172+ Type : schema .TypeString ,
173+ Computed : true ,
174+ Description : `A fingerprint for the labels being applied to this VpnGateway, which is essentially a hash
175+ of the labels set used for optimistic locking. The fingerprint is initially generated by
176+ Compute Engine and changes after every request to modify or update labels.
177+ You must always provide an up-to-date fingerprint hash in order to update or change labels,
178+ otherwise the request will fail with error 412 conditionNotMet.` ,
179+ },
180+ "terraform_labels" : {
181+ Type : schema .TypeMap ,
182+ Computed : true ,
183+ Description : `The combination of labels configured directly on the resource
184+ and default labels configured on the provider.` ,
185+ Elem : & schema.Schema {Type : schema .TypeString },
186+ },
151187 "project" : {
152188 Type : schema .TypeString ,
153189 Optional : true ,
@@ -207,6 +243,18 @@ func resourceComputeHaVpnGatewayCreate(d *schema.ResourceData, meta interface{})
207243 } else if v , ok := d .GetOkExists ("vpn_interfaces" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (vpnInterfacesProp )) && (ok || ! reflect .DeepEqual (v , vpnInterfacesProp )) {
208244 obj ["vpnInterfaces" ] = vpnInterfacesProp
209245 }
246+ labelFingerprintProp , err := expandComputeHaVpnGatewayLabelFingerprint (d .Get ("label_fingerprint" ), d , config )
247+ if err != nil {
248+ return err
249+ } else if v , ok := d .GetOkExists ("label_fingerprint" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (labelFingerprintProp )) && (ok || ! reflect .DeepEqual (v , labelFingerprintProp )) {
250+ obj ["labelFingerprint" ] = labelFingerprintProp
251+ }
252+ labelsProp , err := expandComputeHaVpnGatewayEffectiveLabels (d .Get ("effective_labels" ), d , config )
253+ if err != nil {
254+ return err
255+ } else if v , ok := d .GetOkExists ("effective_labels" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (labelsProp )) && (ok || ! reflect .DeepEqual (v , labelsProp )) {
256+ obj ["labels" ] = labelsProp
257+ }
210258 regionProp , err := expandComputeHaVpnGatewayRegion (d .Get ("region" ), d , config )
211259 if err != nil {
212260 return err
@@ -330,6 +378,18 @@ func resourceComputeHaVpnGatewayRead(d *schema.ResourceData, meta interface{}) e
330378 if err := d .Set ("vpn_interfaces" , flattenComputeHaVpnGatewayVpnInterfaces (res ["vpnInterfaces" ], d , config )); err != nil {
331379 return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
332380 }
381+ if err := d .Set ("labels" , flattenComputeHaVpnGatewayLabels (res ["labels" ], d , config )); err != nil {
382+ return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
383+ }
384+ if err := d .Set ("label_fingerprint" , flattenComputeHaVpnGatewayLabelFingerprint (res ["labelFingerprint" ], d , config )); err != nil {
385+ return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
386+ }
387+ if err := d .Set ("terraform_labels" , flattenComputeHaVpnGatewayTerraformLabels (res ["labels" ], d , config )); err != nil {
388+ return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
389+ }
390+ if err := d .Set ("effective_labels" , flattenComputeHaVpnGatewayEffectiveLabels (res ["labels" ], d , config )); err != nil {
391+ return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
392+ }
333393 if err := d .Set ("region" , flattenComputeHaVpnGatewayRegion (res ["region" ], d , config )); err != nil {
334394 return fmt .Errorf ("Error reading HaVpnGateway: %s" , err )
335395 }
@@ -340,6 +400,80 @@ func resourceComputeHaVpnGatewayRead(d *schema.ResourceData, meta interface{}) e
340400 return nil
341401}
342402
403+ func resourceComputeHaVpnGatewayUpdate (d * schema.ResourceData , meta interface {}) error {
404+ config := meta .(* transport_tpg.Config )
405+ userAgent , err := tpgresource .GenerateUserAgentString (d , config .UserAgent )
406+ if err != nil {
407+ return err
408+ }
409+
410+ billingProject := ""
411+
412+ project , err := tpgresource .GetProject (d , config )
413+ if err != nil {
414+ return fmt .Errorf ("Error fetching project for HaVpnGateway: %s" , err )
415+ }
416+ billingProject = project
417+
418+ d .Partial (true )
419+
420+ if d .HasChange ("label_fingerprint" ) || d .HasChange ("effective_labels" ) {
421+ obj := make (map [string ]interface {})
422+
423+ labelFingerprintProp , err := expandComputeHaVpnGatewayLabelFingerprint (d .Get ("label_fingerprint" ), d , config )
424+ if err != nil {
425+ return err
426+ } else if v , ok := d .GetOkExists ("label_fingerprint" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , labelFingerprintProp )) {
427+ obj ["labelFingerprint" ] = labelFingerprintProp
428+ }
429+ labelsProp , err := expandComputeHaVpnGatewayEffectiveLabels (d .Get ("effective_labels" ), d , config )
430+ if err != nil {
431+ return err
432+ } else if v , ok := d .GetOkExists ("effective_labels" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , labelsProp )) {
433+ obj ["labels" ] = labelsProp
434+ }
435+
436+ url , err := tpgresource .ReplaceVars (d , config , "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/vpnGateways/{{name}}/setLabels" )
437+ if err != nil {
438+ return err
439+ }
440+
441+ headers := make (http.Header )
442+
443+ // err == nil indicates that the billing_project value was found
444+ if bp , err := tpgresource .GetBillingProject (d , config ); err == nil {
445+ billingProject = bp
446+ }
447+
448+ res , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
449+ Config : config ,
450+ Method : "POST" ,
451+ Project : billingProject ,
452+ RawURL : url ,
453+ UserAgent : userAgent ,
454+ Body : obj ,
455+ Timeout : d .Timeout (schema .TimeoutUpdate ),
456+ Headers : headers ,
457+ })
458+ if err != nil {
459+ return fmt .Errorf ("Error updating HaVpnGateway %q: %s" , d .Id (), err )
460+ } else {
461+ log .Printf ("[DEBUG] Finished updating HaVpnGateway %q: %#v" , d .Id (), res )
462+ }
463+
464+ err = ComputeOperationWaitTime (
465+ config , res , project , "Updating HaVpnGateway" , userAgent ,
466+ d .Timeout (schema .TimeoutUpdate ))
467+ if err != nil {
468+ return err
469+ }
470+ }
471+
472+ d .Partial (false )
473+
474+ return resourceComputeHaVpnGatewayRead (d , meta )
475+ }
476+
343477func resourceComputeHaVpnGatewayDelete (d * schema.ResourceData , meta interface {}) error {
344478 config := meta .(* transport_tpg.Config )
345479 userAgent , err := tpgresource .GenerateUserAgentString (d , config .UserAgent )
@@ -496,6 +630,44 @@ func flattenComputeHaVpnGatewayVpnInterfacesInterconnectAttachment(v interface{}
496630 return tpgresource .ConvertSelfLinkToV1 (v .(string ))
497631}
498632
633+ func flattenComputeHaVpnGatewayLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
634+ if v == nil {
635+ return v
636+ }
637+
638+ transformed := make (map [string ]interface {})
639+ if l , ok := d .GetOkExists ("labels" ); ok {
640+ for k := range l .(map [string ]interface {}) {
641+ transformed [k ] = v .(map [string ]interface {})[k ]
642+ }
643+ }
644+
645+ return transformed
646+ }
647+
648+ func flattenComputeHaVpnGatewayLabelFingerprint (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
649+ return v
650+ }
651+
652+ func flattenComputeHaVpnGatewayTerraformLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
653+ if v == nil {
654+ return v
655+ }
656+
657+ transformed := make (map [string ]interface {})
658+ if l , ok := d .GetOkExists ("terraform_labels" ); ok {
659+ for k := range l .(map [string ]interface {}) {
660+ transformed [k ] = v .(map [string ]interface {})[k ]
661+ }
662+ }
663+
664+ return transformed
665+ }
666+
667+ func flattenComputeHaVpnGatewayEffectiveLabels (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
668+ return v
669+ }
670+
499671func flattenComputeHaVpnGatewayRegion (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
500672 if v == nil {
501673 return v
@@ -579,6 +751,21 @@ func expandComputeHaVpnGatewayVpnInterfacesInterconnectAttachment(v interface{},
579751 return f .RelativeLink (), nil
580752}
581753
754+ func expandComputeHaVpnGatewayLabelFingerprint (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
755+ return v , nil
756+ }
757+
758+ func expandComputeHaVpnGatewayEffectiveLabels (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (map [string ]string , error ) {
759+ if v == nil {
760+ return map [string ]string {}, nil
761+ }
762+ m := make (map [string ]string )
763+ for k , val := range v .(map [string ]interface {}) {
764+ m [k ] = val .(string )
765+ }
766+ return m , nil
767+ }
768+
582769func expandComputeHaVpnGatewayRegion (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
583770 f , err := tpgresource .ParseGlobalFieldValue ("regions" , v .(string ), "project" , d , config , true )
584771 if err != nil {
0 commit comments