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
}