istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/serviceentry_simulation_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package core_test
    15  
    16  import (
    17  	"fmt"
    18  	"testing"
    19  
    20  	"istio.io/istio/pilot/pkg/model"
    21  	"istio.io/istio/pilot/pkg/simulation"
    22  	"istio.io/istio/pilot/test/xds"
    23  )
    24  
    25  const se = `
    26  apiVersion: networking.istio.io/v1alpha3
    27  kind: ServiceEntry
    28  metadata:
    29    name: se1
    30  spec:
    31    hosts:
    32    - blah.somedomain
    33    addresses:
    34    - %s
    35    ports:
    36    - number: 9999
    37      name: TCP-9999
    38      protocol: TCP
    39  ---
    40  apiVersion: networking.istio.io/v1alpha3
    41  kind: ServiceEntry
    42  metadata:
    43    name: se2
    44  spec:
    45    hosts:
    46    - blah.somedomain
    47    addresses:
    48    - %s
    49    ports:
    50    - number: 9999
    51      name: TCP-9999
    52      protocol: TCP
    53  ---
    54  apiVersion: networking.istio.io/v1alpha3
    55  kind: VirtualService
    56  metadata:
    57    name: vs1
    58  spec:
    59    hosts:
    60    - blah.somedomain
    61    tls:
    62    - match:
    63      - port: 9999
    64        sniHosts:
    65        - blah.somedomain
    66      route:
    67      - destination:
    68          host: blah.somedomain
    69          port:
    70            number: 9999`
    71  
    72  func TestServiceEntry(t *testing.T) {
    73  	cases := []simulationTest{
    74  		{
    75  			name:       "identical CIDR (ignoring insignificant bits) is dropped",
    76  			config:     fmt.Sprintf(se, "1234:1f1:123:123:f816:3eff:feb8:2287/32", "1234:1f1:123:123:f816:3eff:febf:57ce/32"),
    77  			kubeConfig: "",
    78  			calls: []simulation.Expect{{
    79  				// Expect listener, but no routing
    80  				Name: "defined port",
    81  				Call: simulation.Call{
    82  					Port:       9999,
    83  					HostHeader: "blah.somedomain",
    84  					Address:    "1234:1f1:1:1:1:1:1:1",
    85  					Protocol:   simulation.HTTP,
    86  				},
    87  				Result: simulation.Result{
    88  					ListenerMatched: "0.0.0.0_9999",
    89  					ClusterMatched:  "outbound|9999||blah.somedomain",
    90  				},
    91  			}},
    92  		},
    93  		{
    94  			name: "overlapping CIDR causes multiple filter chain match",
    95  			// One address will be ignorred
    96  			config:     fmt.Sprintf(se, "1234:1f1:123:123:f816:3eff:feb8:2287/16", "1234:1f1:123:123:f816:3eff:febf:57ce/32"),
    97  			kubeConfig: "",
    98  			calls: []simulation.Expect{{
    99  				// Expect listener, but no routing
   100  				Name: "defined port",
   101  				Call: simulation.Call{
   102  					Port:       9999,
   103  					HostHeader: "blah.somedomain",
   104  					Address:    "1234:1f1:1:1:1:1:1:1",
   105  					Protocol:   simulation.HTTP,
   106  				},
   107  				Result: simulation.Result{
   108  					Error:           nil,
   109  					ListenerMatched: "0.0.0.0_9999",
   110  					ClusterMatched:  "outbound|9999||blah.somedomain",
   111  				},
   112  			}},
   113  		},
   114  	}
   115  
   116  	for _, tt := range cases {
   117  		t.Run(tt.name, func(t *testing.T) {
   118  			proxy := &model.Proxy{
   119  				Labels:   map[string]string{"app": "foo"},
   120  				Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "foo"}},
   121  			}
   122  			runSimulationTest(t, proxy, xds.FakeOptions{}, simulationTest{
   123  				name:   tt.name,
   124  				config: tt.config,
   125  				calls:  tt.calls,
   126  			})
   127  		})
   128  	}
   129  }
   130  
   131  const serviceEntriesWithDuplicatedHosts = `
   132  apiVersion: networking.istio.io/v1alpha3
   133  kind: ServiceEntry
   134  metadata:
   135    name: istio-http
   136  spec:
   137    hosts:
   138    - istio.io
   139    location: MESH_EXTERNAL
   140    ports:
   141    - number: 80
   142      name: http
   143      protocol: HTTP
   144    resolution: DNS
   145  ---
   146  apiVersion: networking.istio.io/v1alpha3
   147  kind: ServiceEntry
   148  metadata:
   149    name: istio-https
   150  spec:
   151    hosts:
   152    - istio.io
   153    location: MESH_EXTERNAL
   154    ports:
   155    - number: 443
   156      name: https
   157      protocol: HTTPS
   158    resolution: DNS
   159  `
   160  
   161  func TestServiceEntryDuplicatedHostname(t *testing.T) {
   162  	cases := []simulationTest{
   163  		{
   164  			name:   "service entries with reused hosts should have auto allocated the same IP address",
   165  			config: serviceEntriesWithDuplicatedHosts,
   166  			calls: []simulation.Expect{
   167  				{
   168  					Name: "HTTP call",
   169  					Call: simulation.Call{
   170  						Address:    "240.240.91.120",
   171  						Port:       80,
   172  						HostHeader: "istio.io",
   173  						Protocol:   simulation.HTTP,
   174  					},
   175  					Result: simulation.Result{
   176  						ListenerMatched: "0.0.0.0_80",
   177  						ClusterMatched:  "outbound|80||istio.io",
   178  					},
   179  				},
   180  				{
   181  					Name: "HTTPS call",
   182  					Call: simulation.Call{
   183  						Address:    "240.240.91.120",
   184  						Port:       443,
   185  						HostHeader: "istio.io",
   186  						Protocol:   simulation.HTTP,
   187  						TLS:        simulation.TLS,
   188  					},
   189  					Result: simulation.Result{
   190  						ListenerMatched: "240.240.91.120_443",
   191  						ClusterMatched:  "outbound|443||istio.io",
   192  					},
   193  				},
   194  			},
   195  		},
   196  	}
   197  
   198  	for _, tt := range cases {
   199  		t.Run(tt.name, func(t *testing.T) {
   200  			proxy := &model.Proxy{
   201  				Metadata: &model.NodeMetadata{
   202  					DNSCapture:      true,
   203  					DNSAutoAllocate: true,
   204  				},
   205  			}
   206  			runSimulationTest(t, proxy, xds.FakeOptions{}, simulationTest{
   207  				name:   tt.name,
   208  				config: tt.config,
   209  				calls:  tt.calls,
   210  			})
   211  		})
   212  	}
   213  }