private void ConfigureVirtualHostForPrefixedHost()

in src/routingmanager/Envoy/EnvoyConfigBuilder.cs [309:403]


        private void ConfigureVirtualHostForPrefixedHost(V1Service triggerService, RoutingStateEstablisherInput routingStateEstablisherInput, IEnumerable<PodTriggerConfig> allPodTriggersInNamespace, V1ServicePort servicePort, IList<VirtualHost> httpFilterVirtualHosts)
        {
            foreach (var ingressTrigger in routingStateEstablisherInput.IngressTriggers)
            {
                if (Constants.WildcardHostRegex.IsMatch(ingressTrigger.Host))
                {
                    // Ignore wildcard hosts
                    _log.Verbose("Ignoring wilcard ingress {0}", new PII(ingressTrigger.Host));
                    continue;
                }

                foreach (var podTrigger in allPodTriggersInNamespace)
                {
                    if (servicePort.Port != ingressTrigger.ServicePort
                        // We will be adding rules for ingresses with empty hosts later
                        || (string.IsNullOrWhiteSpace(ingressTrigger.Host) && string.IsNullOrWhiteSpace(ingressTrigger.AgicBackendHostName)))
                    {
                        continue;
                    }

                    var prefixedHost = GetModifiedHost(
                                        string.IsNullOrWhiteSpace(ingressTrigger.AgicBackendHostName) ? ingressTrigger.Host : ingressTrigger.AgicBackendHostName,
                                        podTrigger.RouteOnHeader.Value);
                    _log.Info("Configuring envoy for service '{0}' for port '{1}' : Ingress trigger : '{2}' and pod trigger with route on header value : '{3}'. Host: '{4}'"
                        , new PII(triggerService.Metadata.Name), new PII(servicePort.Port.ToString()), new PII(ingressTrigger.TriggerEntityName), new PII(podTrigger.RouteOnHeader.Value), new PII(prefixedHost));

                    var existingVirtualHost = httpFilterVirtualHosts.Where(vh => vh.Domains.Contains(prefixedHost)).FirstOrDefault();
                    if (existingVirtualHost != null)
                    {
                        if (routingStateEstablisherInput.PodTriggers != null && routingStateEstablisherInput.PodTriggers.Contains(podTrigger))
                        {
                            // This is safe to assume RouteElement and a Cluster are not null as they are defined below.
                            existingVirtualHost.Routes.First().Route.Cluster = string.Format(_serviceStableWithHeaderWithPortsFormatString, podTrigger.RouteOnHeader.Key, podTrigger.RouteOnHeader.Value, servicePort.Port, servicePort.TargetPort.Value);
                        }
                        else
                        {
                            _log.Info("Virtual host for this ingress trigger has already been configured or not required. Skipping.");
                        }
                        continue;
                    }

                    var domains = new List<string> { prefixedHost };
                    var ingressVirtualHost =
                        new VirtualHost
                        {
                            // We are only adding the rule for domain starting with routing header. We are not adding the catch all * here on purpose.
                            // This is because there is at least one pod trigger for sure. We will be adding the * catch all rule as part of that.
                            Name = $"listener_{servicePort.Port}_{servicePort.TargetPort.Value}_route_ingress_withDomain_{string.Join(',', domains)}",
                            Domains = domains,
                            Routes = new List<RouteElement>
                            {
                                new RouteElement
                                {
                                    Match = new Match
                                    {
                                        Prefix = "/"
                                    },
                                    // Will add Route below
                                    RequestHeadersToAdd = new List<RequestHeadersToAdd>
                                    {
                                        new RequestHeadersToAdd
                                        {
                                            Header = new RequestHeaderToAdd
                                            {
                                                Key = podTrigger.RouteOnHeader.Key,
                                                Value = podTrigger.RouteOnHeader.Value
                                            },
                                            Append = false
                                        }
                                    }
                                }
                            }
                        };

                    if (routingStateEstablisherInput.PodTriggers != null && routingStateEstablisherInput.PodTriggers.Contains(podTrigger))
                    {
                        // This means input.TriggerService has an ingress and pod trigger both, so we need to route to service_stable for the given domains
                        ingressVirtualHost.Routes.First().Route = new Route
                        {
                            Cluster = string.Format(_serviceStableWithHeaderWithPortsFormatString, podTrigger.RouteOnHeader.Key, podTrigger.RouteOnHeader.Value, servicePort.Port, servicePort.TargetPort.Value)
                        };
                    }
                    else
                    {
                        ingressVirtualHost.Routes.First().Route = new Route
                        {
                            Cluster = string.Format(_serviceCloneWithPortsFormatString, servicePort.Port, servicePort.TargetPort.Value)
                        };
                    }

                    // Add to the last added listener above. There is always only a single Filter chain and a single filter in that.
                    httpFilterVirtualHosts.Add(ingressVirtualHost);
                }
            }
        }