github.com/cilium/cilium@v1.16.2/pkg/ciliumenvoyconfig/envoy_l7lb_backend_syncer_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ciliumenvoyconfig 5 6 import ( 7 "net/netip" 8 "testing" 9 10 envoy_config_core "github.com/cilium/proxy/go/envoy/config/core/v3" 11 endpointv3 "github.com/cilium/proxy/go/envoy/config/endpoint/v3" 12 _ "github.com/cilium/proxy/go/envoy/config/listener/v3" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 16 "github.com/cilium/cilium/pkg/clustermesh/types" 17 "github.com/cilium/cilium/pkg/loadbalancer" 18 ) 19 20 func Test_filterServiceBackends(t *testing.T) { 21 t.Run("filter by port number", func(t *testing.T) { 22 svc := &loadbalancer.SVC{ 23 Frontend: loadbalancer.L3n4AddrID{ 24 L3n4Addr: loadbalancer.L3n4Addr{ 25 L4Addr: loadbalancer.L4Addr{ 26 Port: 8080, 27 }, 28 }, 29 }, 30 Backends: []*loadbalancer.Backend{ 31 { 32 FEPortName: "http", 33 L3n4Addr: loadbalancer.L3n4Addr{ 34 L4Addr: loadbalancer.L4Addr{ 35 Port: 3000, 36 }, 37 }, 38 }, 39 }, 40 } 41 42 t.Run("all ports are allowed", func(t *testing.T) { 43 backends := filterServiceBackends(svc, nil) 44 assert.Len(t, backends, 1) 45 assert.Len(t, backends["*"], 1) 46 }) 47 t.Run("only http port", func(t *testing.T) { 48 backends := filterServiceBackends(svc, []string{"8080"}) 49 assert.Len(t, backends, 1) 50 assert.Len(t, backends["8080"], 1) 51 }) 52 t.Run("named and number ports", func(t *testing.T) { 53 backends := filterServiceBackends(svc, []string{"8080", "http"}) 54 assert.Len(t, backends, 2) 55 assert.Len(t, backends["8080"], 1) 56 assert.Len(t, backends["http"], 1) 57 }) 58 t.Run("no match", func(t *testing.T) { 59 backends := filterServiceBackends(svc, []string{"8000"}) 60 assert.Len(t, backends, 0) 61 }) 62 }) 63 64 t.Run("filter by port named", func(t *testing.T) { 65 svc := &loadbalancer.SVC{ 66 Frontend: loadbalancer.L3n4AddrID{ 67 L3n4Addr: loadbalancer.L3n4Addr{ 68 L4Addr: loadbalancer.L4Addr{ 69 Port: 8000, 70 }, 71 }, 72 }, 73 Backends: []*loadbalancer.Backend{ 74 { 75 FEPortName: "http", 76 L3n4Addr: loadbalancer.L3n4Addr{ 77 L4Addr: loadbalancer.L4Addr{ 78 Port: 8080, 79 }, 80 }, 81 }, 82 { 83 FEPortName: "https", 84 L3n4Addr: loadbalancer.L3n4Addr{ 85 L4Addr: loadbalancer.L4Addr{ 86 Port: 8443, 87 }, 88 }, 89 }, 90 { 91 FEPortName: "metrics", 92 L3n4Addr: loadbalancer.L3n4Addr{ 93 L4Addr: loadbalancer.L4Addr{ 94 Port: 8081, 95 }, 96 }, 97 }, 98 }, 99 } 100 101 t.Run("all ports are allowed", func(t *testing.T) { 102 backends := filterServiceBackends(svc, nil) 103 assert.Len(t, backends, 1) 104 assert.Len(t, backends["*"], 3) 105 }) 106 t.Run("only http named port", func(t *testing.T) { 107 backends := filterServiceBackends(svc, []string{"http"}) 108 assert.Len(t, backends, 1) 109 assert.Len(t, backends["http"], 1) 110 }) 111 t.Run("multiple named ports", func(t *testing.T) { 112 backends := filterServiceBackends(svc, []string{"http", "metrics"}) 113 assert.Len(t, backends, 2) 114 115 assert.Len(t, backends["http"], 1) 116 assert.Equal(t, (int)(backends["http"][0].Port), 8080) 117 118 assert.Len(t, backends["metrics"], 1) 119 assert.Equal(t, (int)(backends["metrics"][0].Port), 8081) 120 }) 121 }) 122 123 t.Run("filter with preferred backend", func(t *testing.T) { 124 svc := &loadbalancer.SVC{ 125 Frontend: loadbalancer.L3n4AddrID{ 126 L3n4Addr: loadbalancer.L3n4Addr{ 127 L4Addr: loadbalancer.L4Addr{ 128 Port: 8000, 129 }, 130 }, 131 }, 132 Backends: []*loadbalancer.Backend{ 133 { 134 FEPortName: "http", 135 L3n4Addr: loadbalancer.L3n4Addr{ 136 L4Addr: loadbalancer.L4Addr{ 137 Port: 8080, 138 }, 139 }, 140 Preferred: loadbalancer.Preferred(true), 141 }, 142 { 143 FEPortName: "http", 144 L3n4Addr: loadbalancer.L3n4Addr{ 145 L4Addr: loadbalancer.L4Addr{ 146 Port: 8081, 147 }, 148 }, 149 }, 150 { 151 FEPortName: "https", 152 L3n4Addr: loadbalancer.L3n4Addr{ 153 L4Addr: loadbalancer.L4Addr{ 154 Port: 443, 155 }, 156 }, 157 }, 158 { 159 FEPortName: "80", 160 L3n4Addr: loadbalancer.L3n4Addr{ 161 L4Addr: loadbalancer.L4Addr{ 162 Port: 8080, 163 }, 164 }, 165 Preferred: loadbalancer.Preferred(true), 166 }, 167 { 168 FEPortName: "80", 169 L3n4Addr: loadbalancer.L3n4Addr{ 170 L4Addr: loadbalancer.L4Addr{ 171 Port: 8081, 172 }, 173 }, 174 }, 175 }, 176 } 177 178 t.Run("all ports are allowed", func(t *testing.T) { 179 backends := filterServiceBackends(svc, nil) 180 assert.Len(t, backends, 1) 181 assert.Len(t, backends["*"], 2) 182 }) 183 184 t.Run("only named ports", func(t *testing.T) { 185 backends := filterServiceBackends(svc, []string{"http"}) 186 assert.Len(t, backends, 1) 187 assert.Len(t, backends["http"], 1) 188 }) 189 t.Run("multiple named ports", func(t *testing.T) { 190 backends := filterServiceBackends(svc, []string{"http", "https"}) 191 assert.Len(t, backends, 1) 192 193 assert.Len(t, backends["http"], 1) 194 assert.Equal(t, (int)(backends["http"][0].Port), 8080) 195 }) 196 197 t.Run("only port number", func(t *testing.T) { 198 backends := filterServiceBackends(svc, []string{"80"}) 199 assert.Len(t, backends, 1) 200 201 assert.Len(t, backends["80"], 1) 202 assert.Equal(t, (int)(backends["80"][0].Port), 8080) 203 }) 204 }) 205 } 206 207 func TestGetEndpointsForLBBackends(t *testing.T) { 208 testAddr, err := netip.ParseAddr("192.128.1.1") 209 require.NoError(t, err) 210 211 serviceName := loadbalancer.ServiceName{ 212 Namespace: "test-ns", 213 Name: "test-name", 214 Cluster: "test-cluster", 215 } 216 backends := map[string][]*loadbalancer.Backend{ 217 "12000": { 218 { 219 L3n4Addr: *loadbalancer.NewL3n4Addr(loadbalancer.TCP, types.AddrClusterFrom(testAddr, 0), 12000, 3), 220 }, 221 }, 222 "13000": { 223 { 224 L3n4Addr: *loadbalancer.NewL3n4Addr(loadbalancer.TCP, types.AddrClusterFrom(testAddr, 0), 13000, 3), 225 }, 226 }, 227 "*": { 228 { 229 L3n4Addr: *loadbalancer.NewL3n4Addr(loadbalancer.TCP, types.AddrClusterFrom(testAddr, 0), 15000, 3), 230 }, 231 }, 232 } 233 234 endpoints := getEndpointsForLBBackends(serviceName, backends) 235 assert.Len(t, endpoints, 4) 236 237 var allClusterNames []string 238 for _, ep := range endpoints { 239 allClusterNames = append(allClusterNames, ep.GetClusterName()) 240 241 assert.Len(t, ep.GetEndpoints(), 1) 242 assert.Len(t, ep.GetEndpoints()[0].GetLbEndpoints(), 1) 243 assert.Equal(t, ep.GetEndpoints()[0].GetLbEndpoints()[0].GetHostIdentifier().(*endpointv3.LbEndpoint_Endpoint).Endpoint.Address.GetAddress().(*envoy_config_core.Address_SocketAddress).SocketAddress.Address, "192.128.1.1") 244 } 245 246 assert.Contains(t, allClusterNames, "test-cluster/test-ns/test-name:12000") 247 assert.Contains(t, allClusterNames, "test-cluster/test-ns/test-name:13000") 248 assert.Contains(t, allClusterNames, "test-cluster/test-ns/test-name:*") 249 assert.Contains(t, allClusterNames, "test-cluster/test-ns/test-name") 250 }