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);
}
}
}