blob: a3ef549af933ff914a0e916889526a7710f66a6d [file] [log] [blame]
// Copyright Istio Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package loadbalancer
import (
"reflect"
"testing"
)
import (
cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
. "github.com/onsi/gomega"
"google.golang.org/protobuf/types/known/durationpb"
wrappers "google.golang.org/protobuf/types/known/wrapperspb"
meshconfig "istio.io/api/mesh/v1alpha1"
networking "istio.io/api/networking/v1alpha3"
)
import (
"github.com/apache/dubbo-go-pixiu/pilot/pkg/config/memory"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
memregistry "github.com/apache/dubbo-go-pixiu/pilot/pkg/serviceregistry/memory"
"github.com/apache/dubbo-go-pixiu/pkg/config"
"github.com/apache/dubbo-go-pixiu/pkg/config/mesh"
"github.com/apache/dubbo-go-pixiu/pkg/config/protocol"
"github.com/apache/dubbo-go-pixiu/pkg/config/schema/collections"
)
func TestApplyLocalitySetting(t *testing.T) {
locality := &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
}
t.Run("Distribute", func(t *testing.T) {
tests := []struct {
name string
distribute []*networking.LocalityLoadBalancerSetting_Distribute
expected []int
}{
{
name: "distribution between subzones",
distribute: []*networking.LocalityLoadBalancerSetting_Distribute{
{
From: "region1/zone1/subzone1",
To: map[string]uint32{
"region1/zone1/subzone1": 80,
"region1/zone1/subzone2": 15,
"region1/zone1/subzone3": 5,
},
},
},
expected: []int{40, 40, 15, 5, 0, 0, 0},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env := buildEnvForClustersWithDistribute(tt.distribute)
cluster := buildFakeCluster()
ApplyLocalityLBSetting(cluster.LoadAssignment, nil, locality, nil, env.Mesh().LocalityLbSetting, true)
weights := make([]int, 0)
for _, localityEndpoint := range cluster.LoadAssignment.Endpoints {
weights = append(weights, int(localityEndpoint.LoadBalancingWeight.GetValue()))
}
if !reflect.DeepEqual(weights, tt.expected) {
t.Errorf("Got weights %v expected %v", weights, tt.expected)
}
})
}
})
t.Run("Failover: all priorities", func(t *testing.T) {
g := NewWithT(t)
env := buildEnvForClustersWithFailover()
cluster := buildFakeCluster()
ApplyLocalityLBSetting(cluster.LoadAssignment, nil, locality, nil, env.Mesh().LocalityLbSetting, true)
for _, localityEndpoint := range cluster.LoadAssignment.Endpoints {
if localityEndpoint.Locality.Region == locality.Region {
if localityEndpoint.Locality.Zone == locality.Zone {
if localityEndpoint.Locality.SubZone == locality.SubZone {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(0)))
continue
}
g.Expect(localityEndpoint.Priority).To(Equal(uint32(1)))
continue
}
g.Expect(localityEndpoint.Priority).To(Equal(uint32(2)))
continue
}
if localityEndpoint.Locality.Region == "region2" {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(3)))
} else {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(4)))
}
}
})
t.Run("Failover: priorities with gaps", func(t *testing.T) {
g := NewWithT(t)
env := buildEnvForClustersWithFailover()
cluster := buildSmallCluster()
ApplyLocalityLBSetting(cluster.LoadAssignment, nil, locality, nil, env.Mesh().LocalityLbSetting, true)
for _, localityEndpoint := range cluster.LoadAssignment.Endpoints {
if localityEndpoint.Locality.Region == locality.Region {
if localityEndpoint.Locality.Zone == locality.Zone {
if localityEndpoint.Locality.SubZone == locality.SubZone {
t.Errorf("Should not exist")
continue
}
g.Expect(localityEndpoint.Priority).To(Equal(uint32(0)))
continue
}
t.Errorf("Should not exist")
continue
}
if localityEndpoint.Locality.Region == "region2" {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(1)))
} else {
t.Errorf("Should not exist")
}
}
})
t.Run("Failover: priorities with some nil localities", func(t *testing.T) {
g := NewWithT(t)
env := buildEnvForClustersWithFailover()
cluster := buildSmallClusterWithNilLocalities()
ApplyLocalityLBSetting(cluster.LoadAssignment, nil, locality, nil, env.Mesh().LocalityLbSetting, true)
for _, localityEndpoint := range cluster.LoadAssignment.Endpoints {
if localityEndpoint.Locality == nil {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(2)))
} else if localityEndpoint.Locality.Region == locality.Region {
if localityEndpoint.Locality.Zone == locality.Zone {
if localityEndpoint.Locality.SubZone == locality.SubZone {
t.Errorf("Should not exist")
continue
}
g.Expect(localityEndpoint.Priority).To(Equal(uint32(0)))
continue
}
t.Errorf("Should not exist")
continue
} else if localityEndpoint.Locality.Region == "region2" {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(1)))
} else {
t.Errorf("Should not exist")
}
}
})
t.Run("Failover: with locality lb disabled", func(t *testing.T) {
g := NewWithT(t)
cluster := buildSmallClusterWithNilLocalities()
lbsetting := &networking.LocalityLoadBalancerSetting{
Enabled: &wrappers.BoolValue{Value: false},
}
ApplyLocalityLBSetting(cluster.LoadAssignment, nil, locality, nil, lbsetting, true)
for _, localityEndpoint := range cluster.LoadAssignment.Endpoints {
g.Expect(localityEndpoint.Priority).To(Equal(uint32(0)))
}
})
t.Run("FailoverPriority", func(t *testing.T) {
tests := []struct {
name string
failoverPriority []string
proxyLabels map[string]string
expected []*endpoint.LocalityLbEndpoints
}{
{
name: "match none label",
failoverPriority: []string{"topology.istio.io/network", "topology.istio.io/cluster"},
proxyLabels: map[string]string{
"topology.istio.io/network": "test",
"topology.istio.io/cluster": "test",
},
expected: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("1.1.1.1"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("2.2.2.2"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 2,
},
Priority: 0,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("3.3.3.3"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("4.4.4.4"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 2,
},
Priority: 0,
},
},
},
{
name: "match network label",
failoverPriority: []string{"topology.istio.io/network", "topology.istio.io/cluster"},
proxyLabels: map[string]string{
"topology.istio.io/network": "n1",
"topology.istio.io/cluster": "test",
},
expected: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("1.1.1.1"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 0,
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("2.2.2.2"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 1,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("3.3.3.3"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 0,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("4.4.4.4"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 1,
},
},
},
{
name: "not match the first n label",
failoverPriority: []string{"topology.istio.io/network", "topology.istio.io/cluster"},
proxyLabels: map[string]string{
"topology.istio.io/network": "test",
"topology.istio.io/cluster": "c1",
},
expected: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("1.1.1.1"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("2.2.2.2"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 2,
},
Priority: 0,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("3.3.3.3"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("4.4.4.4"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 2,
},
Priority: 0,
},
},
},
{
name: "match all labels",
failoverPriority: []string{"key", "topology.istio.io/network", "topology.istio.io/cluster"},
proxyLabels: map[string]string{
"key": "value",
"topology.istio.io/network": "n2",
"topology.istio.io/cluster": "c2",
},
expected: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("2.2.2.2"), // match [key, network, cluster]
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 0,
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("1.1.1.1"), // match no label
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 3,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("4.4.4.4"), // match [key, network]
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 1,
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("3.3.3.3"), // match [key]
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
Priority: 2,
},
},
},
}
wrappedEndpoints := buildWrappedLocalityLbEndpoints()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env := buildEnvForClustersWithFailoverPriority(tt.failoverPriority)
cluster := buildFakeCluster()
ApplyLocalityLBSetting(cluster.LoadAssignment, wrappedEndpoints, locality, tt.proxyLabels, env.Mesh().LocalityLbSetting, true)
if len(cluster.LoadAssignment.Endpoints) != len(tt.expected) {
t.Fatalf("expected endpoints %d but got %d", len(cluster.LoadAssignment.Endpoints), len(tt.expected))
}
for i := range cluster.LoadAssignment.Endpoints {
if cluster.LoadAssignment.Endpoints[i].LoadBalancingWeight.GetValue() != tt.expected[i].LoadBalancingWeight.GetValue() {
t.Errorf("Got unexpected lb weight %v expected %v", cluster.LoadAssignment.Endpoints[i].LoadBalancingWeight, tt.expected[i].LoadBalancingWeight)
}
if cluster.LoadAssignment.Endpoints[i].Priority != tt.expected[i].Priority {
t.Errorf("Got unexpected priority %v expected %v", cluster.LoadAssignment.Endpoints[i].Priority, tt.expected[i].Priority)
}
}
})
}
})
}
func TestGetLocalityLbSetting(t *testing.T) {
// dummy config for test
failover := []*networking.LocalityLoadBalancerSetting_Failover{nil}
cases := []struct {
name string
mesh *networking.LocalityLoadBalancerSetting
dr *networking.LocalityLoadBalancerSetting
expected *networking.LocalityLoadBalancerSetting
}{
{
"all disabled",
nil,
nil,
nil,
},
{
"mesh only",
&networking.LocalityLoadBalancerSetting{},
nil,
&networking.LocalityLoadBalancerSetting{},
},
{
"dr only",
nil,
&networking.LocalityLoadBalancerSetting{},
&networking.LocalityLoadBalancerSetting{},
},
{
"dr only override",
nil,
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: true}},
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: true}},
},
{
"both",
&networking.LocalityLoadBalancerSetting{},
&networking.LocalityLoadBalancerSetting{Failover: failover},
&networking.LocalityLoadBalancerSetting{Failover: failover},
},
{
"mesh disabled",
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: false}},
nil,
nil,
},
{
"dr disabled",
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: true}},
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: false}},
nil,
},
{
"dr enabled override mesh disabled",
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: false}},
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: true}},
&networking.LocalityLoadBalancerSetting{Enabled: &wrappers.BoolValue{Value: true}},
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
got := GetLocalityLbSetting(tt.mesh, tt.dr)
if !reflect.DeepEqual(tt.expected, got) {
t.Fatalf("Expected: %v, got: %v", tt.expected, got)
}
})
}
}
func buildEnvForClustersWithDistribute(distribute []*networking.LocalityLoadBalancerSetting_Distribute) *model.Environment {
serviceDiscovery := memregistry.NewServiceDiscovery(&model.Service{
Hostname: "test.example.org",
DefaultAddress: "1.1.1.1",
Ports: model.PortList{
&model.Port{
Name: "default",
Port: 8080,
Protocol: protocol.HTTP,
},
},
})
meshConfig := &meshconfig.MeshConfig{
ConnectTimeout: &durationpb.Duration{
Seconds: 10,
Nanos: 1,
},
LocalityLbSetting: &networking.LocalityLoadBalancerSetting{
Distribute: distribute,
},
}
configStore := model.MakeIstioStore(memory.Make(collections.Pilot))
env := &model.Environment{
ServiceDiscovery: serviceDiscovery,
ConfigStore: configStore,
Watcher: mesh.NewFixedWatcher(meshConfig),
}
env.PushContext = model.NewPushContext()
env.Init()
_ = env.PushContext.InitContext(env, nil, nil)
env.PushContext.SetDestinationRules([]config.Config{
{
Meta: config.Meta{
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
Name: "acme",
},
Spec: &networking.DestinationRule{
Host: "test.example.org",
TrafficPolicy: &networking.TrafficPolicy{
OutlierDetection: &networking.OutlierDetection{},
},
},
},
})
return env
}
func buildEnvForClustersWithFailover() *model.Environment {
serviceDiscovery := memregistry.NewServiceDiscovery(&model.Service{
Hostname: "test.example.org",
DefaultAddress: "1.1.1.1",
Ports: model.PortList{
&model.Port{
Name: "default",
Port: 8080,
Protocol: protocol.HTTP,
},
},
})
meshConfig := &meshconfig.MeshConfig{
ConnectTimeout: &durationpb.Duration{
Seconds: 10,
Nanos: 1,
},
LocalityLbSetting: &networking.LocalityLoadBalancerSetting{
Failover: []*networking.LocalityLoadBalancerSetting_Failover{
{
From: "region1",
To: "region2",
},
},
},
}
configStore := model.MakeIstioStore(memory.Make(collections.Pilot))
env := &model.Environment{
ServiceDiscovery: serviceDiscovery,
ConfigStore: configStore,
Watcher: mesh.NewFixedWatcher(meshConfig),
}
env.PushContext = model.NewPushContext()
env.Init()
_ = env.PushContext.InitContext(env, nil, nil)
env.PushContext.SetDestinationRules([]config.Config{
{
Meta: config.Meta{
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
Name: "acme",
},
Spec: &networking.DestinationRule{
Host: "test.example.org",
TrafficPolicy: &networking.TrafficPolicy{
OutlierDetection: &networking.OutlierDetection{},
},
},
},
})
return env
}
func buildEnvForClustersWithFailoverPriority(failoverPriority []string) *model.Environment {
serviceDiscovery := memregistry.NewServiceDiscovery(&model.Service{
Hostname: "test.example.org",
DefaultAddress: "1.1.1.1",
Ports: model.PortList{
&model.Port{
Name: "default",
Port: 8080,
Protocol: protocol.HTTP,
},
},
})
meshConfig := &meshconfig.MeshConfig{
ConnectTimeout: &durationpb.Duration{
Seconds: 10,
Nanos: 1,
},
LocalityLbSetting: &networking.LocalityLoadBalancerSetting{
FailoverPriority: failoverPriority,
},
}
configStore := model.MakeIstioStore(memory.Make(collections.Pilot))
env := &model.Environment{
ServiceDiscovery: serviceDiscovery,
ConfigStore: configStore,
Watcher: mesh.NewFixedWatcher(meshConfig),
}
env.PushContext = model.NewPushContext()
env.Init()
_ = env.PushContext.InitContext(env, nil, nil)
env.PushContext.SetDestinationRules([]config.Config{
{
Meta: config.Meta{
GroupVersionKind: collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind(),
Name: "acme",
},
Spec: &networking.DestinationRule{
Host: "test.example.org",
TrafficPolicy: &networking.TrafficPolicy{
OutlierDetection: &networking.OutlierDetection{},
},
},
},
})
return env
}
func buildFakeCluster() *cluster.Cluster {
return &cluster.Cluster{
Name: "outbound|8080||test.example.org",
LoadAssignment: &endpoint.ClusterLoadAssignment{
ClusterName: "outbound|8080||test.example.org",
Endpoints: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone2",
},
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone3",
},
},
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone2",
SubZone: "",
},
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "",
SubZone: "",
},
},
{
Locality: &core.Locality{
Region: "region3",
Zone: "",
SubZone: "",
},
},
},
},
}
}
func buildSmallCluster() *cluster.Cluster {
return &cluster.Cluster{
Name: "outbound|8080||test.example.org",
LoadAssignment: &endpoint.ClusterLoadAssignment{
ClusterName: "outbound|8080||test.example.org",
Endpoints: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone2",
},
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone1",
SubZone: "subzone2",
},
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone1",
SubZone: "subzone2",
},
},
},
},
}
}
func buildSmallClusterWithNilLocalities() *cluster.Cluster {
return &cluster.Cluster{
Name: "outbound|8080||test.example.org",
LoadAssignment: &endpoint.ClusterLoadAssignment{
ClusterName: "outbound|8080||test.example.org",
Endpoints: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone2",
},
},
{},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone1",
SubZone: "subzone2",
},
},
},
},
}
}
func buildSmallClusterForFailOverPriority() *cluster.Cluster {
return &cluster.Cluster{
Name: "outbound|8080||test.example.org",
LoadAssignment: &endpoint.ClusterLoadAssignment{
ClusterName: "outbound|8080||test.example.org",
Endpoints: []*endpoint.LocalityLbEndpoints{
{
Locality: &core.Locality{
Region: "region1",
Zone: "zone1",
SubZone: "subzone1",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("1.1.1.1"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("2.2.2.2"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
},
{
Locality: &core.Locality{
Region: "region2",
Zone: "zone2",
SubZone: "subzone2",
},
LbEndpoints: []*endpoint.LbEndpoint{
{
HostIdentifier: buildEndpoint("3.3.3.3"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
{
HostIdentifier: buildEndpoint("4.4.4.4"),
LoadBalancingWeight: &wrappers.UInt32Value{
Value: 1,
},
},
},
},
},
},
}
}
func buildEndpoint(ip string) *endpoint.LbEndpoint_Endpoint {
return &endpoint.LbEndpoint_Endpoint{
Endpoint: &endpoint.Endpoint{
Address: &core.Address{
Address: &core.Address_SocketAddress{
SocketAddress: &core.SocketAddress{
Address: ip,
PortSpecifier: &core.SocketAddress_PortValue{
PortValue: 10001,
},
},
},
},
},
}
}
func buildWrappedLocalityLbEndpoints() []*WrappedLocalityLbEndpoints {
cluster := buildSmallClusterForFailOverPriority()
return []*WrappedLocalityLbEndpoints{
{
IstioEndpoints: []*model.IstioEndpoint{
{
Labels: map[string]string{
"topology.istio.io/network": "n1",
"topology.istio.io/cluster": "c1",
},
Address: "1.1.1.1",
},
{
Labels: map[string]string{
"key": "value",
"topology.istio.io/network": "n2",
"topology.istio.io/cluster": "c2",
},
Address: "2.2.2.2",
},
},
LocalityLbEndpoints: cluster.LoadAssignment.Endpoints[0],
},
{
IstioEndpoints: []*model.IstioEndpoint{
{
Labels: map[string]string{
"key": "value",
"topology.istio.io/network": "n1",
"topology.istio.io/cluster": "c3",
},
Address: "3.3.3.3",
},
{
Labels: map[string]string{
"key": "value",
"topology.istio.io/network": "n2",
"topology.istio.io/cluster": "c4",
},
Address: "4.4.4.4",
},
},
LocalityLbEndpoints: cluster.LoadAssignment.Endpoints[1],
},
}
}