func convertGateways()

in pkg/ingress/kube/gateway/istio/conversion.go [1569:1705]


func convertGateways(r configContext) ([]config.Config, map[parentKey][]*parentInfo, sets.String) {
	// result stores our generated Istio Gateways
	result := []config.Config{}
	// gwMap stores an index to access parentInfo (which corresponds to a Kubernetes Gateway)
	gwMap := map[parentKey][]*parentInfo{}
	// namespaceLabelReferences keeps track of all namespace label keys referenced by Gateways. This is
	// used to ensure we handle namespace updates for those keys.
	namespaceLabelReferences := sets.New[string]()
	classes := getGatewayClasses(r.GatewayResources)
	for _, obj := range r.Gateway {
		obj := obj
		kgw := obj.Spec.(*k8s.GatewaySpec)
		controllerName, f := classes[string(kgw.GatewayClassName)]
		if !f {
			// No gateway class found, this may be meant for another controller; should be skipped.
			continue
		}
		classInfo, f := classInfos[controllerName]
		if !f {
			continue
		}
		if classInfo.disableRouteGeneration {
			// We found it, but don't want to handle this class
			continue
		}

		servers := []*istio.Server{}

		// Start - Updated by Higress
		// Extract the addresses. A gateway will bind to a specific Service
		gatewayServices, useDefaultService, err := extractGatewayServices(r.GatewayResources, kgw, obj)
		if len(gatewayServices) == 0 && !useDefaultService && err != nil {
			// Short circuit if it's a hard failure
			reportGatewayStatus(r, obj, gatewayServices, servers, err)
			continue
		}
		// End - Updated by Higress
		for i, l := range kgw.Listeners {
			i := i
			namespaceLabelReferences.InsertAll(getNamespaceLabelReferences(l.AllowedRoutes)...)
			server, ok := buildListener(r, obj, l, i, controllerName)
			if !ok {
				continue
			}
			servers = append(servers, server)
			if controllerName == constants.ManagedGatewayMeshController {
				// Waypoint doesn't actually convert the routes to VirtualServices
				continue
			}
			var selector map[string]string
			meta := parentMeta(obj, &l.Name)
			if len(gatewayServices) != 0 {
				meta[model.InternalGatewayServiceAnnotation] = strings.Join(gatewayServices, ",")
			} else if useDefaultService {
				selector = r.GatewayResources.DefaultGatewaySelector
			} else {
				// Protective programming. This shouldn't happen.
				continue
			}
			// End - Updated by Higress
			// Each listener generates an Istio Gateway with a single Server. This allows binding to a specific listener.
			gatewayConfig := config.Config{
				Meta: config.Meta{
					CreationTimestamp: obj.CreationTimestamp,
					GroupVersionKind:  gvk.Gateway,
					Name:              fmt.Sprintf("%s-%s-%s", obj.Name, constants.KubernetesGatewayName, l.Name),
					Annotations:       meta,
					Namespace:         obj.Namespace,
					Domain:            r.Domain,
				},
				Spec: &istio.Gateway{
					Servers: []*istio.Server{server},
					// Start - Added by Higress
					Selector: selector,
					// End - Added by Higress
				},
			}
			ref := parentKey{
				Kind:      gvk.KubernetesGateway,
				Name:      obj.Name,
				Namespace: obj.Namespace,
			}
			if _, f := gwMap[ref]; !f {
				gwMap[ref] = []*parentInfo{}
			}

			allowed, _ := generateSupportedKinds(l)
			pri := &parentInfo{
				InternalName:     obj.Namespace + "/" + gatewayConfig.Name,
				AllowedKinds:     allowed,
				Hostnames:        server.Hosts,
				OriginalHostname: string(ptr.OrEmpty(l.Hostname)),
				SectionName:      l.Name,
				Port:             l.Port,
			}
			pri.ReportAttachedRoutes = func() {
				reportListenerAttachedRoutes(i, obj, pri.AttachedRoutes)
			}
			gwMap[ref] = append(gwMap[ref], pri)
			result = append(result, gatewayConfig)
		}

		// If "gateway.istio.io/alias-for" annotation is present, any Route
		// that binds to the gateway will bind to its alias instead.
		// The typical usage is when the original gateway is not managed by the gateway controller
		// but the ( generated ) alias is. This allows people to build their own
		// gateway controllers on top of Istio Gateway Controller.
		if obj.Annotations != nil && obj.Annotations[gatewayAliasForAnnotationKey] != "" {
			ref := parentKey{
				Kind:      gvk.KubernetesGateway,
				Name:      obj.Annotations[gatewayAliasForAnnotationKey],
				Namespace: obj.Namespace,
			}
			alias := parentKey{
				Kind:      gvk.KubernetesGateway,
				Name:      obj.Name,
				Namespace: obj.Namespace,
			}
			gwMap[ref] = gwMap[alias]
		}

		reportGatewayStatus(r, obj, gatewayServices, servers, err)
	}
	// Insert a parent for Mesh references.
	gwMap[meshParentKey] = []*parentInfo{
		{
			InternalName: "mesh",
			// Mesh has no configurable AllowedKinds, so allow all supported
			AllowedKinds: []k8s.RouteGroupKind{
				{Group: (*k8s.Group)(ptr.Of(gvk.HTTPRoute.Group)), Kind: k8s.Kind(gvk.HTTPRoute.Kind)},
				{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)},
				{Group: (*k8s.Group)(ptr.Of(gvk.TLSRoute.Group)), Kind: k8s.Kind(gvk.TLSRoute.Kind)},
			},
		},
	}
	return result, gwMap, namespaceLabelReferences
}