in pkg/providers/gateway/translation/gateway_httproute.go [133:280]
func (t *translator) TranslateGatewayHTTPRouteV1beta1(httpRoute *gatewayv1beta1.HTTPRoute) (*translation.TranslateContext, error) {
ctx := translation.DefaultEmptyTranslateContext()
var hosts []string
for _, hostname := range httpRoute.Spec.Hostnames {
hosts = append(hosts, string(hostname))
// TODO: See the document of gatewayv1beta1.Listener.Hostname
_ = gatewayv1beta1.Listener{}.Hostname
// For HTTPRoute and TLSRoute resources, there is an interaction with the
// `spec.hostnames` array. When both listener and route specify hostnames,
// there MUST be an intersection between the values for a Route to be
// accepted. For more information, refer to the Route specific Hostnames
// documentation.
}
rules := httpRoute.Spec.Rules
for i, rule := range rules {
backends := rule.BackendRefs
if len(backends) == 0 {
continue
}
var ruleUpstreams []*apisixv1.Upstream
var weightedUpstreams []apisixv1.TrafficSplitConfigRuleWeightedUpstream
for j, backend := range backends {
// TODO: Support filters
// filters := backend.Filters
var kind string
if backend.Kind == nil {
kind = "service"
} else {
kind = strings.ToLower(string(*backend.Kind))
}
if kind != "service" {
log.Warnw(fmt.Sprintf("ignore non-service kind at Rules[%v].BackendRefs[%v]", i, j),
zap.String("kind", kind),
)
continue
}
var ns string
if backend.Namespace == nil {
ns = httpRoute.Namespace
} else {
ns = string(*backend.Namespace)
}
//if ns != httpRoute.Namespace {
// TODO: check gatewayv1beta1.ReferencePolicy
//}
if backend.Port == nil {
log.Warnw(fmt.Sprintf("ignore nil port at Rules[%v].BackendRefs[%v]", i, j),
zap.String("kind", kind),
)
continue
}
ups, err := t.KubeTranslator.TranslateService(ns, string(backend.Name), "", int32(*backend.Port))
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("failed to translate Rules[%v].BackendRefs[%v]", i, j))
}
ups.Name = apisixv1.ComposeUpstreamName(ns, string(backend.Name), "", int32(*backend.Port), types.ResolveGranularity.Endpoint)
// APISIX limits max length of label value
// https://github.com/apache/apisix/blob/5b95b85faea3094d5e466ee2d39a52f1f805abbb/apisix/schema_def.lua#L85
ups.Labels["meta_namespace"] = utils.TruncateString(ns, 64)
ups.Labels["meta_backend"] = utils.TruncateString(string(backend.Name), 64)
ups.Labels["meta_port"] = fmt.Sprintf("%v", int32(*backend.Port))
ups.ID = id.GenID(ups.Name)
log.Debugw("translated HTTPRoute upstream",
zap.Int("backendRefs_index", j),
zap.String("backendRefs_name", string(backend.Name)),
zap.String("name", ups.Name),
)
ctx.AddUpstream(ups)
ruleUpstreams = append(ruleUpstreams, ups)
if backend.Weight == nil {
weightedUpstreams = append(weightedUpstreams, apisixv1.TrafficSplitConfigRuleWeightedUpstream{
UpstreamID: ups.ID,
Weight: 1, // 1 is default value of BackendRef
})
} else {
weightedUpstreams = append(weightedUpstreams, apisixv1.TrafficSplitConfigRuleWeightedUpstream{
UpstreamID: ups.ID,
Weight: int(*backend.Weight),
})
}
}
if len(ruleUpstreams) == 0 {
log.Warnw(fmt.Sprintf("ignore all-failed backend refs at Rules[%v]", i),
zap.Any("BackendRefs", rule.BackendRefs),
)
continue
}
matches := rule.Matches
if len(matches) == 0 {
defaultType := gatewayv1beta1.PathMatchPathPrefix
defaultValue := "/"
matches = []gatewayv1beta1.HTTPRouteMatch{
{
Path: &gatewayv1beta1.HTTPPathMatch{
Type: &defaultType,
Value: &defaultValue,
},
},
}
}
plugins := t.generatePluginsFromHTTPRouteFilter(httpRoute.Namespace, rule.Filters)
for j, match := range matches {
route, err := t.translateGatewayHTTPRouteMatch(&match)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("failed to translate Rules[%v].Matches[%v]", i, j))
}
name := apisixv1.ComposeRouteName(httpRoute.Namespace, httpRoute.Name, fmt.Sprintf("%d-%d", i, j))
route.ID = id.GenID(name)
route.Hosts = hosts
route.Plugins = plugins
// Bind Upstream
if len(ruleUpstreams) == 1 {
route.UpstreamId = ruleUpstreams[0].ID
} else if len(ruleUpstreams) > 0 {
route.Plugins["traffic-split"] = &apisixv1.TrafficSplitConfig{
Rules: []apisixv1.TrafficSplitConfigRule{
{
WeightedUpstreams: weightedUpstreams,
},
},
}
}
ctx.AddRoute(route)
}
// TODO: Support filters
// filters := rule.Filters
}
return ctx, nil
}