-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
173 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,173 @@ | ||
package common | ||
|
||
import ( | ||
"k8s.io/utils/ptr" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" | ||
) | ||
|
||
type KuadrantTopology struct { | ||
// Gateway -> []Policy | ||
gatewayPolicies map[client.ObjectKey][]KuadrantPolicy | ||
|
||
// Policy -> HTTPRoute | ||
policyRoute map[client.ObjectKey]*gatewayapiv1beta1.HTTPRoute | ||
|
||
// Gateway -> []HTTPRoute (routes not targeted directly by any policy) | ||
freeRoutes map[client.ObjectKey][]*gatewayapiv1beta1.HTTPRoute | ||
} | ||
|
||
func NewKuadrantTopology(gateways []*gatewayapiv1beta1.Gateway, routes []*gatewayapiv1beta1.HTTPRoute, policy []KuadrantPolicy) *KuadrantTopology { | ||
// TODO | ||
return &KuadrantTopology{} | ||
func NewKuadrantTopology(gateways []*gatewayapiv1beta1.Gateway, routes []*gatewayapiv1beta1.HTTPRoute, policies []KuadrantPolicy) *KuadrantTopology { | ||
t := NewGatewayAPITopology(gateways, routes) | ||
|
||
return &KuadrantTopology{ | ||
gatewayPolicies: buildGatewayPoliciesIndex(t, policies), | ||
policyRoute: buildPolicyRouteIndex(t, policies), | ||
freeRoutes: buildFreeRoutesIndex(t, policies), | ||
} | ||
} | ||
|
||
func (k *KuadrantTopology) PoliciesFromGateway(gateway *gatewayapiv1beta1.Gateway) []KuadrantPolicy { | ||
return k.gatewayPolicies[client.ObjectKeyFromObject(gateway)] | ||
} | ||
|
||
func (k *KuadrantTopology) GetPolicyHTTPRoute(policy KuadrantPolicy) *gatewayapiv1beta1.HTTPRoute { | ||
return k.policyRoute[client.ObjectKeyFromObject(policy)] | ||
} | ||
|
||
func (k *KuadrantTopology) GetFreeRoutes(gateway *gatewayapiv1beta1.Gateway) []*gatewayapiv1beta1.HTTPRoute { | ||
return k.freeRoutes[client.ObjectKeyFromObject(gateway)] | ||
} | ||
|
||
func buildGatewayPoliciesIndex(t *gatewayAPITopology, policies []KuadrantPolicy) map[client.ObjectKey][]KuadrantPolicy { | ||
// Build Gateway -> []Policy index with all the policies affecting the indexed gateway | ||
index := make(map[client.ObjectKey][]KuadrantPolicy, 0) | ||
|
||
for _, policy := range policies { | ||
if gateway := t.GatewayFromPolicy(policy); gateway != nil { | ||
// policy targeting a gateway | ||
policies := index[client.ObjectKeyFromObject(gateway)] | ||
policies = append(policies, policy) | ||
index[client.ObjectKeyFromObject(gateway)] = policies | ||
} else if route := t.RouteFromPolicy(policy); route != nil { | ||
// policy targeting a route | ||
routeParents := t.GetRouteParents(route) | ||
for _, routeParent := range routeParents { | ||
policies := index[client.ObjectKeyFromObject(routeParent)] | ||
policies = append(policies, policy) | ||
index[client.ObjectKeyFromObject(routeParent)] = policies | ||
} | ||
} | ||
|
||
// skipping the policy as it does not target neither a valid route nor a valid gateway | ||
} | ||
|
||
return index | ||
} | ||
|
||
func buildPolicyRouteIndex(t *gatewayAPITopology, policies []KuadrantPolicy) map[client.ObjectKey]*gatewayapiv1beta1.HTTPRoute { | ||
// Build Policy -> HTTPRoute index with the route targeted by the indexed policy | ||
index := make(map[client.ObjectKey]*gatewayapiv1beta1.HTTPRoute, 0) | ||
for _, policy := range policies { | ||
if route := t.RouteFromPolicy(policy); route != nil { | ||
index[client.ObjectKeyFromObject(policy)] = route | ||
} | ||
} | ||
|
||
return index | ||
} | ||
|
||
func buildFreeRoutesIndex(t *gatewayAPITopology, policies []KuadrantPolicy) map[client.ObjectKey][]*gatewayapiv1beta1.HTTPRoute { | ||
// Build Gateway -> []HTTPRoute index with all the routes not targeted by a policy | ||
index := make(map[client.ObjectKey][]*gatewayapiv1beta1.HTTPRoute, 0) | ||
|
||
routesTargetedByPolicy := make(map[client.ObjectKey]bool, 0) | ||
for _, policy := range policies { | ||
if route := t.RouteFromPolicy(policy); route != nil { | ||
routesTargetedByPolicy[client.ObjectKeyFromObject(route)] = true | ||
} | ||
} | ||
|
||
for _, gateway := range t.GetGateways() { | ||
var gatewayFreeRoutes []*gatewayapiv1beta1.HTTPRoute | ||
for _, route := range t.GetGatewayRoutes(gateway) { | ||
if !routesTargetedByPolicy[client.ObjectKeyFromObject(route)] { | ||
gatewayFreeRoutes = append(gatewayFreeRoutes, route) | ||
} | ||
} | ||
|
||
if len(gatewayFreeRoutes) > 0 { | ||
index[client.ObjectKeyFromObject(gateway)] = gatewayFreeRoutes | ||
} | ||
} | ||
|
||
return index | ||
} | ||
|
||
type gatewayAPITopology struct { | ||
gatewaysIndex map[client.ObjectKey]*gatewayapiv1beta1.Gateway | ||
routesIndex map[client.ObjectKey]*gatewayapiv1beta1.HTTPRoute | ||
} | ||
|
||
func NewGatewayAPITopology(gateways []*gatewayapiv1beta1.Gateway, routes []*gatewayapiv1beta1.HTTPRoute) *gatewayAPITopology { | ||
// First build topology with them all | ||
// TODO Secondly, just valid gateways and accepted HTTPRoutes | ||
|
||
gatewaysIndex := make(map[client.ObjectKey]*gatewayapiv1beta1.Gateway, 0) | ||
for _, gateway := range gateways { | ||
gatewaysIndex[client.ObjectKeyFromObject(gateway)] = gateway | ||
} | ||
|
||
routesIndex := make(map[client.ObjectKey]*gatewayapiv1beta1.HTTPRoute, 0) | ||
for _, route := range routes { | ||
routesIndex[client.ObjectKeyFromObject(route)] = route | ||
} | ||
|
||
return &gatewayAPITopology{ | ||
gatewaysIndex: gatewaysIndex, | ||
routesIndex: routesIndex, | ||
} | ||
} | ||
|
||
func (g *gatewayAPITopology) GatewayFromPolicy(policy KuadrantPolicy) *gatewayapiv1beta1.Gateway { | ||
// Return gateway targeted by the kuadrant policy | ||
|
||
if !IsTargetRefGateway(policy.GetTargetRef()) { | ||
return nil | ||
} | ||
|
||
namespace := string(ptr.Deref(policy.GetTargetRef().Namespace, policy.GetWrappedNamespace())) | ||
|
||
gwKey := client.ObjectKey{Name: string(policy.GetTargetRef().Name), Namespace: namespace} | ||
|
||
return g.gatewaysIndex[gwKey] | ||
} | ||
|
||
func (g *gatewayAPITopology) RouteFromPolicy(policy KuadrantPolicy) *gatewayapiv1beta1.HTTPRoute { | ||
// Return route targeted by the kuadrant policy | ||
|
||
if !IsTargetRefHTTPRoute(policy.GetTargetRef()) { | ||
return nil | ||
} | ||
|
||
namespace := string(ptr.Deref(policy.GetTargetRef().Namespace, policy.GetWrappedNamespace())) | ||
|
||
routeKey := client.ObjectKey{Name: string(policy.GetTargetRef().Name), Namespace: namespace} | ||
|
||
return g.routesIndex[routeKey] | ||
} | ||
|
||
func (g *gatewayAPITopology) GetRouteParents(route *gatewayapiv1beta1.HTTPRoute) []*gatewayapiv1beta1.Gateway { | ||
// TODO | ||
return nil | ||
} | ||
|
||
func (k *KuadrantTopology) GetPolicyHTTPRoute(policy KuadrantPolicy) *gatewayapiv1beta1.HTTPRoute { | ||
func (g *gatewayAPITopology) GetGateways() []*gatewayapiv1beta1.Gateway { | ||
// TODO | ||
return nil | ||
} | ||
|
||
func (k *KuadrantTopology) GetFreeRoutes(gateway *gatewayapiv1beta1.Gateway) []*gatewayapiv1beta1.HTTPRoute { | ||
func (g *gatewayAPITopology) GetGatewayRoutes(gateway *gatewayapiv1beta1.Gateway) []*gatewayapiv1beta1.HTTPRoute { | ||
// TODO | ||
return nil | ||
} |