istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/waypoint.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  
    15  package core
    16  
    17  import (
    18  	"istio.io/istio/pilot/pkg/model"
    19  	"istio.io/istio/pkg/config/host"
    20  	"istio.io/istio/pkg/maps"
    21  	"istio.io/istio/pkg/util/sets"
    22  )
    23  
    24  const (
    25  	// ConnectTerminate is the name for the resources associated with the termination of HTTP CONNECT.
    26  	ConnectTerminate = "connect_terminate"
    27  
    28  	// MainInternalName is the name for the resources associated with the main (non-tunnel) internal listener.
    29  	MainInternalName = "main_internal"
    30  
    31  	// ConnectOriginate is the name for the resources associated with the origination of HTTP CONNECT.
    32  	ConnectOriginate = "connect_originate"
    33  
    34  	// EncapClusterName is the name of the cluster used for traffic to the connect_originate listener.
    35  	EncapClusterName = "encap"
    36  
    37  	// ConnectUpgradeType is the type of upgrade for HTTP CONNECT.
    38  	ConnectUpgradeType = "CONNECT"
    39  )
    40  
    41  type waypointServices struct {
    42  	services        map[host.Name]*model.Service
    43  	orderedServices []*model.Service
    44  }
    45  
    46  // findWaypointResources returns workloads and services associated with the waypoint proxy
    47  func findWaypointResources(node *model.Proxy, push *model.PushContext) ([]model.WorkloadInfo, *waypointServices) {
    48  	key := model.WaypointKeyForProxy(node)
    49  	workloads := push.WorkloadsForWaypoint(key)
    50  	serviceInfos := push.ServicesForWaypoint(key)
    51  
    52  	waypointServices := &waypointServices{}
    53  	for _, s := range serviceInfos {
    54  		hostName := host.Name(s.Service.Hostname)
    55  		svc, ok := push.ServiceIndex.HostnameAndNamespace[hostName][s.Namespace]
    56  		if !ok {
    57  			continue
    58  		}
    59  		if waypointServices.services == nil {
    60  			waypointServices.services = map[host.Name]*model.Service{}
    61  		}
    62  		waypointServices.services[hostName] = svc
    63  	}
    64  
    65  	unorderedServices := maps.Values(waypointServices.services)
    66  	if len(serviceInfos) > 0 {
    67  		waypointServices.orderedServices = model.SortServicesByCreationTime(unorderedServices)
    68  	}
    69  	return workloads, waypointServices
    70  }
    71  
    72  // filterWaypointOutboundServices is used to determine the set of outbound clusters we need to build for waypoints.
    73  // Waypoints typically only have inbound clusters, except in cases where we have a route from
    74  // a service owned by the waypoint to a service not owned by the waypoint.
    75  // It looks at:
    76  // * referencedServices: all services referenced by mesh virtual services
    77  // * waypointServices: all services owned by this waypoint
    78  // * extraServices: extra services required by the waypoint (extensions configured, etc)
    79  // * all services
    80  // We want to find any VirtualServices that are from a waypointServices to a non-waypointService
    81  func filterWaypointOutboundServices(
    82  	referencedServices map[string]sets.String,
    83  	waypointServices map[host.Name]*model.Service,
    84  	extraServices sets.String,
    85  	services []*model.Service,
    86  ) []*model.Service {
    87  	outboundServices := sets.New[string]()
    88  	for waypointService := range waypointServices {
    89  		refs := referencedServices[waypointService.String()]
    90  		for ref := range refs {
    91  			// We reference this service. Is it "inbound" for the waypoint or "outbound"?
    92  			ws, f := waypointServices[host.Name(ref)]
    93  			if !f || ws.MeshExternal {
    94  				outboundServices.Insert(ref)
    95  			}
    96  		}
    97  	}
    98  	res := make([]*model.Service, 0, len(outboundServices))
    99  	for _, s := range services {
   100  		if outboundServices.Contains(s.Hostname.String()) || extraServices.Contains(s.Hostname.String()) {
   101  			res = append(res, s)
   102  		}
   103  	}
   104  	return res
   105  }