Skip to content

Commit 890787b

Browse files
committed
feat: Add support for HTTPRoutePolicy in HTTPRoute reconciliation
1 parent 2b5f4fb commit 890787b

File tree

4 files changed

+118
-20
lines changed

4 files changed

+118
-20
lines changed

internal/controller/httproute_controller.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
6565
},
6666
),
6767
).
68+
Watches(&v1alpha1.HTTPRoutePolicy{},
69+
handler.EnqueueRequestsFromMapFunc(r.listHTTPRouteByHTTPRoutePolicy),
70+
).
6871
Complete(r)
6972
}
7073

@@ -232,6 +235,36 @@ func (r *HTTPRouteReconciler) listHTTPRoutesForGateway(ctx context.Context, obj
232235
return requests
233236
}
234237

238+
func (r *HTTPRouteReconciler) listHTTPRouteByHTTPRoutePolicy(ctx context.Context, obj client.Object) (requests []reconcile.Request) {
239+
httpRoutePolicy, ok := obj.(*v1alpha1.HTTPRoutePolicy)
240+
if !ok {
241+
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to HTTPRoutePolicy")
242+
return nil
243+
}
244+
245+
var keys = make(map[client.ObjectKey]struct{})
246+
for _, ref := range httpRoutePolicy.Spec.TargetRefs {
247+
if ref.Kind == "HTTPRoute" {
248+
keys[client.ObjectKey{
249+
Namespace: obj.GetNamespace(),
250+
Name: string(ref.Name),
251+
}] = struct{}{}
252+
}
253+
}
254+
for key := range keys {
255+
var httpRoute gatewayv1.HTTPRoute
256+
if err := r.Get(ctx, key, &httpRoute); err != nil {
257+
r.Log.Error(err, "failed to get httproute by HTTPRoutePolicy targetRef", "HTTPRoutePolicy", obj.GetName())
258+
continue
259+
}
260+
requests = append(requests, reconcile.Request{
261+
NamespacedName: key,
262+
})
263+
}
264+
265+
return requests
266+
}
267+
235268
func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.TranslateContext) error {
236269
var terr error
237270
for _, backend := range tctx.BackendRefs {
@@ -290,7 +323,7 @@ func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.Transla
290323
return terr
291324
}
292325

293-
func (t *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext, httpRoute *gatewayv1.HTTPRoute) error {
326+
func (r *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext, httpRoute *gatewayv1.HTTPRoute) error {
294327
var terror error
295328
for _, rule := range httpRoute.Spec.Rules {
296329
for _, filter := range rule.Filters {
@@ -299,7 +332,7 @@ func (t *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext,
299332
}
300333
if filter.ExtensionRef.Kind == "PluginConfig" {
301334
pluginconfig := new(v1alpha1.PluginConfig)
302-
if err := t.Get(context.Background(), client.ObjectKey{
335+
if err := r.Get(context.Background(), client.ObjectKey{
303336
Namespace: httpRoute.GetNamespace(),
304337
Name: string(filter.ExtensionRef.Name),
305338
}, pluginconfig); err != nil {
@@ -340,6 +373,20 @@ func (t *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext,
340373
},
341374
})
342375
}
376+
377+
var httpRoutePolicyList v1alpha1.HTTPRoutePolicyList
378+
var ruleName string
379+
if rule.Name != nil {
380+
ruleName = string(*rule.Name)
381+
}
382+
key := indexer.GenHTTPRoutePolicyIndexKey(v1alpha1.GroupVersion.Group, "HTTPRoute", httpRoute.GetNamespace(), httpRoute.GetName(), ruleName)
383+
if err := r.List(context.Background(), &httpRoutePolicyList, client.MatchingFields{indexer.HTTPRoutePolicy: key}); err != nil {
384+
terror = err
385+
continue
386+
}
387+
for _, item := range httpRoutePolicyList.Items {
388+
tctx.HTTPRoutePolicies[ruleName] = append(tctx.HTTPRoutePolicies[key], item.Spec)
389+
}
343390
}
344391

345392
return terror

internal/controller/indexer/indexer.go

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ package indexer
33
import (
44
"context"
55

6-
"github.com/api7/api7-ingress-controller/api/v1alpha1"
76
networkingv1 "k8s.io/api/networking/v1"
7+
"k8s.io/apimachinery/pkg/runtime/schema"
88
ctrl "sigs.k8s.io/controller-runtime"
99
"sigs.k8s.io/controller-runtime/pkg/client"
1010
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
11+
12+
"github.com/api7/api7-ingress-controller/api/v1alpha1"
1113
)
1214

1315
const (
14-
ServiceIndexRef = "serviceRefs"
15-
ExtensionRef = "extensionRef"
16-
ParametersRef = "parametersRef"
17-
ParentRefs = "parentRefs"
18-
IngressClass = "ingressClass"
19-
SecretIndexRef = "secretRefs"
20-
IngressClassRef = "ingressClassRef"
21-
ConsumerGatewayRef = "consumerGatewayRef"
16+
ServiceIndexRef = "serviceRefs"
17+
ExtensionRef = "extensionRef"
18+
ParametersRef = "parametersRef"
19+
ParentRefs = "parentRefs"
20+
IngressClass = "ingressClass"
21+
SecretIndexRef = "secretRefs"
22+
IngressClassRef = "ingressClassRef"
23+
ConsumerGatewayRef = "consumerGatewayRef"
24+
HTTPRoutePolicyTargetRef = "httpRoutePolicyTargetRef"
25+
HTTPRoutePolicy = "httpRoutePolicy"
2226
)
2327

2428
func SetupIndexer(mgr ctrl.Manager) error {
@@ -128,6 +132,16 @@ func setupHTTPRouteIndexer(mgr ctrl.Manager) error {
128132
); err != nil {
129133
return err
130134
}
135+
136+
if err := mgr.GetFieldIndexer().IndexField(
137+
context.Background(),
138+
&v1alpha1.HTTPRoutePolicy{},
139+
HTTPRoutePolicy,
140+
HTTPRoutePolicyIndexFunc,
141+
); err != nil {
142+
return err
143+
}
144+
131145
return nil
132146
}
133147

@@ -281,6 +295,23 @@ func HTTPRouteExtensionIndexFunc(rawObj client.Object) []string {
281295
return keys
282296
}
283297

298+
func GenHTTPRoutePolicyIndexKey(group, kind, namespace, name, sectionName string) string {
299+
return schema.GroupKind{Group: group, Kind: kind}.String() + "/" + client.ObjectKey{Namespace: namespace, Name: name}.String() + "/" + sectionName
300+
}
301+
302+
func HTTPRoutePolicyIndexFunc(rawObj client.Object) []string {
303+
hrp := rawObj.(*v1alpha1.HTTPRoutePolicy)
304+
var keys = make([]string, 0, len(hrp.Spec.TargetRefs))
305+
for i, ref := range hrp.Spec.TargetRefs {
306+
var sectionName string
307+
if ref.SectionName != nil {
308+
sectionName = string(*ref.SectionName)
309+
}
310+
keys[i] = GenHTTPRoutePolicyIndexKey(v1alpha1.GroupVersion.Group, string(ref.Kind), hrp.GetNamespace(), string(ref.Name), sectionName)
311+
}
312+
return keys
313+
}
314+
284315
func GatewayParametersRefIndexFunc(rawObj client.Object) []string {
285316
gw := rawObj.(*gatewayv1.Gateway)
286317
if gw.Spec.Infrastructure != nil && gw.Spec.Infrastructure.ParametersRef != nil {

internal/provider/adc/translator/httproute.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,23 @@ func (t *Translator) fillPluginFromHTTPRequestRedirectFilter(plugins adctypes.Pl
231231
plugin.URI = uri
232232
}
233233

234+
func (t *Translator) fillHTTPRoutePolicies(tctx *provider.TranslateContext, rule gatewayv1.HTTPRouteRule, routes []*adctypes.Route) {
235+
var ruleName string
236+
if rule.Name != nil {
237+
ruleName = string(*rule.Name)
238+
}
239+
specs, ok := tctx.HTTPRoutePolicies[ruleName]
240+
if !ok || len(specs) == 0 {
241+
return
242+
}
243+
for _, route := range routes {
244+
for _, spec := range specs {
245+
route.Priority = spec.Priority
246+
route.Vars = append(route.Vars, spec.Vars...)
247+
}
248+
}
249+
}
250+
234251
func (t *Translator) translateEndpointSlice(weight int, endpointSlices []discoveryv1.EndpointSlice) adctypes.UpstreamNodes {
235252
var nodes adctypes.UpstreamNodes
236253
if len(endpointSlices) == 0 {
@@ -337,6 +354,7 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou
337354
route.Labels = labels
338355
routes = append(routes, route)
339356
}
357+
t.fillHTTPRoutePolicies(tctx, rule, routes)
340358
service.Routes = routes
341359

342360
result.Services = append(result.Services, service)

internal/provider/provider.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import (
77
discoveryv1 "k8s.io/api/discovery/v1"
88
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
99

10-
"github.com/api7/api7-ingress-controller/api/v1alpha1"
1110
"k8s.io/apimachinery/pkg/types"
1211
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
"github.com/api7/api7-ingress-controller/api/v1alpha1"
1314
)
1415

1516
type Provider interface {
@@ -18,14 +19,15 @@ type Provider interface {
1819
}
1920

2021
type TranslateContext struct {
21-
BackendRefs []gatewayv1.BackendRef
22-
GatewayTLSConfig []gatewayv1.GatewayTLSConfig
23-
GatewayProxy *v1alpha1.GatewayProxy
24-
Credentials []v1alpha1.Credential
25-
EndpointSlices map[types.NamespacedName][]discoveryv1.EndpointSlice
26-
Secrets map[types.NamespacedName]*corev1.Secret
27-
PluginConfigs map[types.NamespacedName]*v1alpha1.PluginConfig
28-
Services map[types.NamespacedName]*corev1.Service
22+
BackendRefs []gatewayv1.BackendRef
23+
GatewayTLSConfig []gatewayv1.GatewayTLSConfig
24+
GatewayProxy *v1alpha1.GatewayProxy
25+
Credentials []v1alpha1.Credential
26+
EndpointSlices map[types.NamespacedName][]discoveryv1.EndpointSlice
27+
Secrets map[types.NamespacedName]*corev1.Secret
28+
PluginConfigs map[types.NamespacedName]*v1alpha1.PluginConfig
29+
Services map[types.NamespacedName]*corev1.Service
30+
HTTPRoutePolicies map[string][]v1alpha1.HTTPRoutePolicySpec
2931
}
3032

3133
func NewDefaultTranslateContext() *TranslateContext {

0 commit comments

Comments
 (0)