@@ -665,6 +665,103 @@ load balancing cannot be used with the other. For more information, refer to
665665[Choosing a load balancer](https://cloud.google.com/load-balancing/docs/backend-service). Default value: "EXTERNAL" Possible values: ["EXTERNAL", "INTERNAL_SELF_MANAGED", "EXTERNAL_MANAGED"]` ,
666666 Default : "EXTERNAL" ,
667667 },
668+ "locality_lb_policies" : {
669+ Type : schema .TypeList ,
670+ Optional : true ,
671+ Description : `A list of locality load balancing policies to be used in order of
672+ preference. Either the policy or the customPolicy field should be set.
673+ Overrides any value set in the localityLbPolicy field.
674+
675+ localityLbPolicies is only supported when the BackendService is referenced
676+ by a URL Map that is referenced by a target gRPC proxy that has the
677+ validateForProxyless field set to true.` ,
678+ Elem : & schema.Resource {
679+ Schema : map [string ]* schema.Schema {
680+ "custom_policy" : {
681+ Type : schema .TypeList ,
682+ Optional : true ,
683+ Description : `The configuration for a custom policy implemented by the user and
684+ deployed with the client.` ,
685+ MaxItems : 1 ,
686+ Elem : & schema.Resource {
687+ Schema : map [string ]* schema.Schema {
688+ "name" : {
689+ Type : schema .TypeString ,
690+ Required : true ,
691+ Description : `Identifies the custom policy.
692+
693+ The value should match the type the custom implementation is registered
694+ with on the gRPC clients. It should follow protocol buffer
695+ message naming conventions and include the full path (e.g.
696+ myorg.CustomLbPolicy). The maximum length is 256 characters.
697+
698+ Note that specifying the same custom policy more than once for a
699+ backend is not a valid configuration and will be rejected.` ,
700+ },
701+ "data" : {
702+ Type : schema .TypeString ,
703+ Optional : true ,
704+ Description : `An optional, arbitrary JSON object with configuration data, understood
705+ by a locally installed custom policy implementation.` ,
706+ },
707+ },
708+ },
709+ ExactlyOneOf : []string {},
710+ },
711+ "policy" : {
712+ Type : schema .TypeList ,
713+ Optional : true ,
714+ Description : `The configuration for a built-in load balancing policy.` ,
715+ MaxItems : 1 ,
716+ Elem : & schema.Resource {
717+ Schema : map [string ]* schema.Schema {
718+ "name" : {
719+ Type : schema .TypeString ,
720+ Required : true ,
721+ ValidateFunc : validateEnum ([]string {"ROUND_ROBIN" , "LEAST_REQUEST" , "RING_HASH" , "RANDOM" , "ORIGINAL_DESTINATION" , "MAGLEV" }),
722+ Description : `The name of a locality load balancer policy to be used. The value
723+ should be one of the predefined ones as supported by localityLbPolicy,
724+ although at the moment only ROUND_ROBIN is supported.
725+
726+ This field should only be populated when the customPolicy field is not
727+ used.
728+
729+ Note that specifying the same policy more than once for a backend is
730+ not a valid configuration and will be rejected.
731+
732+ The possible values are:
733+
734+ * 'ROUND_ROBIN': This is a simple policy in which each healthy backend
735+ is selected in round robin order.
736+
737+ * 'LEAST_REQUEST': An O(1) algorithm which selects two random healthy
738+ hosts and picks the host which has fewer active requests.
739+
740+ * 'RING_HASH': The ring/modulo hash load balancer implements consistent
741+ hashing to backends. The algorithm has the property that the
742+ addition/removal of a host from a set of N hosts only affects
743+ 1/N of the requests.
744+
745+ * 'RANDOM': The load balancer selects a random healthy host.
746+
747+ * 'ORIGINAL_DESTINATION': Backend host is selected based on the client
748+ connection metadata, i.e., connections are opened
749+ to the same address as the destination address of
750+ the incoming connection before the connection
751+ was redirected to the load balancer.
752+
753+ * 'MAGLEV': used as a drop in replacement for the ring hash load balancer.
754+ Maglev is not as stable as ring hash but has faster table lookup
755+ build times and host selection times. For more information about
756+ Maglev, refer to https://ai.google/research/pubs/pub44824 Possible values: ["ROUND_ROBIN", "LEAST_REQUEST", "RING_HASH", "RANDOM", "ORIGINAL_DESTINATION", "MAGLEV"]` ,
757+ },
758+ },
759+ },
760+ ExactlyOneOf : []string {},
761+ },
762+ },
763+ },
764+ },
668765 "locality_lb_policy" : {
669766 Type : schema .TypeString ,
670767 Optional : true ,
@@ -1224,6 +1321,12 @@ func resourceComputeBackendServiceCreate(d *schema.ResourceData, meta interface{
12241321 } else if v , ok := d .GetOkExists ("locality_lb_policy" ); ! isEmptyValue (reflect .ValueOf (localityLbPolicyProp )) && (ok || ! reflect .DeepEqual (v , localityLbPolicyProp )) {
12251322 obj ["localityLbPolicy" ] = localityLbPolicyProp
12261323 }
1324+ localityLbPoliciesProp , err := expandComputeBackendServiceLocalityLbPolicies (d .Get ("locality_lb_policies" ), d , config )
1325+ if err != nil {
1326+ return err
1327+ } else if v , ok := d .GetOkExists ("locality_lb_policies" ); ! isEmptyValue (reflect .ValueOf (localityLbPoliciesProp )) && (ok || ! reflect .DeepEqual (v , localityLbPoliciesProp )) {
1328+ obj ["localityLbPolicies" ] = localityLbPoliciesProp
1329+ }
12271330 nameProp , err := expandComputeBackendServiceName (d .Get ("name" ), d , config )
12281331 if err != nil {
12291332 return err
@@ -1487,6 +1590,9 @@ func resourceComputeBackendServiceRead(d *schema.ResourceData, meta interface{})
14871590 if err := d .Set ("locality_lb_policy" , flattenComputeBackendServiceLocalityLbPolicy (res ["localityLbPolicy" ], d , config )); err != nil {
14881591 return fmt .Errorf ("Error reading BackendService: %s" , err )
14891592 }
1593+ if err := d .Set ("locality_lb_policies" , flattenComputeBackendServiceLocalityLbPolicies (res ["localityLbPolicies" ], d , config )); err != nil {
1594+ return fmt .Errorf ("Error reading BackendService: %s" , err )
1595+ }
14901596 if err := d .Set ("name" , flattenComputeBackendServiceName (res ["name" ], d , config )); err != nil {
14911597 return fmt .Errorf ("Error reading BackendService: %s" , err )
14921598 }
@@ -1636,6 +1742,12 @@ func resourceComputeBackendServiceUpdate(d *schema.ResourceData, meta interface{
16361742 } else if v , ok := d .GetOkExists ("locality_lb_policy" ); ! isEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , localityLbPolicyProp )) {
16371743 obj ["localityLbPolicy" ] = localityLbPolicyProp
16381744 }
1745+ localityLbPoliciesProp , err := expandComputeBackendServiceLocalityLbPolicies (d .Get ("locality_lb_policies" ), d , config )
1746+ if err != nil {
1747+ return err
1748+ } else if v , ok := d .GetOkExists ("locality_lb_policies" ); ! isEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , localityLbPoliciesProp )) {
1749+ obj ["localityLbPolicies" ] = localityLbPoliciesProp
1750+ }
16391751 nameProp , err := expandComputeBackendServiceName (d .Get ("name" ), d , config )
16401752 if err != nil {
16411753 return err
@@ -2608,6 +2720,65 @@ func flattenComputeBackendServiceLocalityLbPolicy(v interface{}, d *schema.Resou
26082720 return v
26092721}
26102722
2723+ func flattenComputeBackendServiceLocalityLbPolicies (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2724+ if v == nil {
2725+ return v
2726+ }
2727+ l := v .([]interface {})
2728+ transformed := make ([]interface {}, 0 , len (l ))
2729+ for _ , raw := range l {
2730+ original := raw .(map [string ]interface {})
2731+ if len (original ) < 1 {
2732+ // Do not include empty json objects coming back from the api
2733+ continue
2734+ }
2735+ transformed = append (transformed , map [string ]interface {}{
2736+ "policy" : flattenComputeBackendServiceLocalityLbPoliciesPolicy (original ["policy" ], d , config ),
2737+ "custom_policy" : flattenComputeBackendServiceLocalityLbPoliciesCustomPolicy (original ["customPolicy" ], d , config ),
2738+ })
2739+ }
2740+ return transformed
2741+ }
2742+ func flattenComputeBackendServiceLocalityLbPoliciesPolicy (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2743+ if v == nil {
2744+ return nil
2745+ }
2746+ original := v .(map [string ]interface {})
2747+ if len (original ) == 0 {
2748+ return nil
2749+ }
2750+ transformed := make (map [string ]interface {})
2751+ transformed ["name" ] =
2752+ flattenComputeBackendServiceLocalityLbPoliciesPolicyName (original ["name" ], d , config )
2753+ return []interface {}{transformed }
2754+ }
2755+ func flattenComputeBackendServiceLocalityLbPoliciesPolicyName (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2756+ return v
2757+ }
2758+
2759+ func flattenComputeBackendServiceLocalityLbPoliciesCustomPolicy (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2760+ if v == nil {
2761+ return nil
2762+ }
2763+ original := v .(map [string ]interface {})
2764+ if len (original ) == 0 {
2765+ return nil
2766+ }
2767+ transformed := make (map [string ]interface {})
2768+ transformed ["name" ] =
2769+ flattenComputeBackendServiceLocalityLbPoliciesCustomPolicyName (original ["name" ], d , config )
2770+ transformed ["data" ] =
2771+ flattenComputeBackendServiceLocalityLbPoliciesCustomPolicyData (original ["data" ], d , config )
2772+ return []interface {}{transformed }
2773+ }
2774+ func flattenComputeBackendServiceLocalityLbPoliciesCustomPolicyName (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2775+ return v
2776+ }
2777+
2778+ func flattenComputeBackendServiceLocalityLbPoliciesCustomPolicyData (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
2779+ return v
2780+ }
2781+
26112782func flattenComputeBackendServiceName (v interface {}, d * schema.ResourceData , config * Config ) interface {} {
26122783 return v
26132784}
@@ -3678,6 +3849,92 @@ func expandComputeBackendServiceLocalityLbPolicy(v interface{}, d TerraformResou
36783849 return v , nil
36793850}
36803851
3852+ func expandComputeBackendServiceLocalityLbPolicies (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3853+ l := v .([]interface {})
3854+ req := make ([]interface {}, 0 , len (l ))
3855+ for _ , raw := range l {
3856+ if raw == nil {
3857+ continue
3858+ }
3859+ original := raw .(map [string ]interface {})
3860+ transformed := make (map [string ]interface {})
3861+
3862+ transformedPolicy , err := expandComputeBackendServiceLocalityLbPoliciesPolicy (original ["policy" ], d , config )
3863+ if err != nil {
3864+ return nil , err
3865+ } else if val := reflect .ValueOf (transformedPolicy ); val .IsValid () && ! isEmptyValue (val ) {
3866+ transformed ["policy" ] = transformedPolicy
3867+ }
3868+
3869+ transformedCustomPolicy , err := expandComputeBackendServiceLocalityLbPoliciesCustomPolicy (original ["custom_policy" ], d , config )
3870+ if err != nil {
3871+ return nil , err
3872+ } else if val := reflect .ValueOf (transformedCustomPolicy ); val .IsValid () && ! isEmptyValue (val ) {
3873+ transformed ["customPolicy" ] = transformedCustomPolicy
3874+ }
3875+
3876+ req = append (req , transformed )
3877+ }
3878+ return req , nil
3879+ }
3880+
3881+ func expandComputeBackendServiceLocalityLbPoliciesPolicy (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3882+ l := v .([]interface {})
3883+ if len (l ) == 0 || l [0 ] == nil {
3884+ return nil , nil
3885+ }
3886+ raw := l [0 ]
3887+ original := raw .(map [string ]interface {})
3888+ transformed := make (map [string ]interface {})
3889+
3890+ transformedName , err := expandComputeBackendServiceLocalityLbPoliciesPolicyName (original ["name" ], d , config )
3891+ if err != nil {
3892+ return nil , err
3893+ } else if val := reflect .ValueOf (transformedName ); val .IsValid () && ! isEmptyValue (val ) {
3894+ transformed ["name" ] = transformedName
3895+ }
3896+
3897+ return transformed , nil
3898+ }
3899+
3900+ func expandComputeBackendServiceLocalityLbPoliciesPolicyName (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3901+ return v , nil
3902+ }
3903+
3904+ func expandComputeBackendServiceLocalityLbPoliciesCustomPolicy (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3905+ l := v .([]interface {})
3906+ if len (l ) == 0 || l [0 ] == nil {
3907+ return nil , nil
3908+ }
3909+ raw := l [0 ]
3910+ original := raw .(map [string ]interface {})
3911+ transformed := make (map [string ]interface {})
3912+
3913+ transformedName , err := expandComputeBackendServiceLocalityLbPoliciesCustomPolicyName (original ["name" ], d , config )
3914+ if err != nil {
3915+ return nil , err
3916+ } else if val := reflect .ValueOf (transformedName ); val .IsValid () && ! isEmptyValue (val ) {
3917+ transformed ["name" ] = transformedName
3918+ }
3919+
3920+ transformedData , err := expandComputeBackendServiceLocalityLbPoliciesCustomPolicyData (original ["data" ], d , config )
3921+ if err != nil {
3922+ return nil , err
3923+ } else if val := reflect .ValueOf (transformedData ); val .IsValid () && ! isEmptyValue (val ) {
3924+ transformed ["data" ] = transformedData
3925+ }
3926+
3927+ return transformed , nil
3928+ }
3929+
3930+ func expandComputeBackendServiceLocalityLbPoliciesCustomPolicyName (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3931+ return v , nil
3932+ }
3933+
3934+ func expandComputeBackendServiceLocalityLbPoliciesCustomPolicyData (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
3935+ return v , nil
3936+ }
3937+
36813938func expandComputeBackendServiceName (v interface {}, d TerraformResourceData , config * Config ) (interface {}, error ) {
36823939 return v , nil
36833940}
0 commit comments