in pkg/ingress/kube/gateway/istio/conversion.go [654:744]
func referenceAllowed(
parent *parentInfo,
routeKind config.GroupVersionKind,
parentRef parentReference,
hostnames []k8s.Hostname,
namespace string,
) *ParentError {
if parentRef.Kind == gvk.Service {
// TODO: check if the service reference is valid
if false {
return &ParentError{
Reason: ParentErrorParentRefConflict,
Message: fmt.Sprintf("parent service: %q is invalid", parentRef.Name),
}
}
} else {
// First, check section and port apply. This must come first
if parentRef.Port != 0 && parentRef.Port != parent.Port {
return &ParentError{
Reason: ParentErrorNotAccepted,
Message: fmt.Sprintf("port %v not found", parentRef.Port),
}
}
if len(parentRef.SectionName) > 0 && parentRef.SectionName != parent.SectionName {
return &ParentError{
Reason: ParentErrorNotAccepted,
Message: fmt.Sprintf("sectionName %q not found", parentRef.SectionName),
}
}
// Next check the hostnames are a match. This is a bi-directional wildcard match. Only one route
// hostname must match for it to be allowed (but the others will be filtered at runtime)
// If either is empty its treated as a wildcard which always matches
if len(hostnames) == 0 {
hostnames = []k8s.Hostname{"*"}
}
if len(parent.Hostnames) > 0 {
// TODO: the spec actually has a label match, not a string match. That is, *.com does not match *.apple.com
// We are doing a string match here
matched := false
hostMatched := false
for _, routeHostname := range hostnames {
for _, parentHostNamespace := range parent.Hostnames {
spl := strings.Split(parentHostNamespace, "/")
parentNamespace, parentHostname := spl[0], spl[1]
hostnameMatch := host.Name(parentHostname).Matches(host.Name(routeHostname))
namespaceMatch := parentNamespace == "*" || parentNamespace == namespace
hostMatched = hostMatched || hostnameMatch
if hostnameMatch && namespaceMatch {
matched = true
break
}
}
}
if !matched {
if hostMatched {
return &ParentError{
Reason: ParentErrorNotAllowed,
Message: fmt.Sprintf(
"hostnames matched parent hostname %q, but namespace %q is not allowed by the parent",
parent.OriginalHostname, namespace,
),
}
}
return &ParentError{
Reason: ParentErrorNoHostname,
Message: fmt.Sprintf(
"no hostnames matched parent hostname %q",
parent.OriginalHostname,
),
}
}
}
}
// Also make sure this route kind is allowed
matched := false
for _, ak := range parent.AllowedKinds {
if string(ak.Kind) == routeKind.Kind && ptr.OrDefault((*string)(ak.Group), gvk.GatewayClass.Group) == routeKind.Group {
matched = true
break
}
}
if !matched {
return &ParentError{
Reason: ParentErrorNotAllowed,
Message: fmt.Sprintf("kind %v is not allowed", routeKind),
}
}
return nil
}