in pkg/providers/ingress/translation/translator.go [138:244]
func (t *translator) translateIngressV1(ing *networkingv1.Ingress, skipVerify bool) (*translation.TranslateContext, error) {
ctx := translation.DefaultEmptyTranslateContext()
ingress := t.TranslateAnnotations(ing.Annotations)
// add https
for _, tls := range ing.Spec.TLS {
ssl, err := t.TranslateIngressTLS(ing.Namespace, ing.Name, tls.SecretName, tls.Hosts)
if err != nil {
log.Errorw("failed to translate ingress tls to apisix tls",
zap.Error(err),
zap.Any("ingress", ing),
)
return nil, err
}
ctx.AddSSL(ssl)
}
ns := ing.Namespace
if ingress.ServiceNamespace != "" {
ns = ingress.ServiceNamespace
}
for _, rule := range ing.Spec.Rules {
if rule.HTTP == nil {
continue
}
for _, pathRule := range rule.HTTP.Paths {
var (
ups *apisixv1.Upstream
err error
)
if pathRule.Backend.Service != nil {
if skipVerify {
ups = t.translateDefaultUpstreamFromIngressV1(ns, pathRule.Backend.Service)
} else {
ups, err = t.translateUpstreamFromIngressV1(ns, pathRule.Backend.Service)
if err != nil {
log.Errorw("failed to translate ingress backend to upstream",
zap.Error(err),
zap.Any("ingress", ing),
)
return nil, err
}
}
if ingress.UpstreamScheme != "" {
ups.Scheme = ingress.UpstreamScheme
}
ctx.AddUpstream(ups)
}
uris := []string{pathRule.Path}
var nginxVars []kubev2.ApisixRouteHTTPMatchExpr
if pathRule.PathType != nil {
if *pathRule.PathType == networkingv1.PathTypePrefix {
// As per the specification of Ingress path matching rule:
// if the last element of the path is a substring of the
// last element in request path, it is not a match, e.g. /foo/bar
// matches /foo/bar/baz, but does not match /foo/barbaz.
// While in APISIX, /foo/bar matches both /foo/bar/baz and
// /foo/barbaz.
// In order to be conformant with Ingress specification, here
// we create two paths here, the first is the path itself
// (exact match), the other is path + "/*" (prefix match).
prefix := pathRule.Path
if strings.HasSuffix(prefix, "/") {
prefix += "*"
} else {
prefix += "/*"
}
uris = append(uris, prefix)
} else if *pathRule.PathType == networkingv1.PathTypeImplementationSpecific && ingress.UseRegex {
nginxVars = append(nginxVars, kubev2.ApisixRouteHTTPMatchExpr{
Subject: kubev2.ApisixRouteHTTPMatchExprSubject{
Scope: apisixconst.ScopePath,
},
Op: apisixconst.OpRegexMatch,
Value: &pathRule.Path,
})
uris = []string{"/*"}
}
}
route := apisixv1.NewDefaultRoute()
route.Name = composeIngressRouteName(ing.Namespace, ing.Name, rule.Host, pathRule.Path)
route.ID = id.GenID(route.Name)
route.Host = rule.Host
route.Uris = uris
route.EnableWebsocket = ingress.EnableWebSocket
if len(nginxVars) > 0 {
routeVars, err := t.ApisixTranslator.TranslateRouteMatchExprs(nginxVars)
if err != nil {
return nil, err
}
route.Vars = routeVars
route.Priority = _regexPriority
}
if len(ingress.Plugins) > 0 {
route.Plugins = *(ingress.Plugins.DeepCopy())
}
if ingress.PluginConfigName != "" {
route.PluginConfigId = id.GenID(apisixv1.ComposePluginConfigName(ing.Namespace, ingress.PluginConfigName))
}
if ups != nil {
route.UpstreamId = ups.ID
}
ctx.AddRoute(route)
}
}
return ctx, nil
}