Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
eguzki committed Oct 7, 2023
1 parent 310a675 commit a84fb4d
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 20 deletions.
4 changes: 2 additions & 2 deletions controllers/authpolicy_auth_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ func (r *AuthPolicyReconciler) desiredAuthConfig(ap *api.AuthPolicy, targetNetwo

func (r *AuthPolicyReconciler) policyHosts(ap *api.AuthPolicy, targetNetworkObject client.Object) ([]string, error) {
if len(ap.Spec.AuthRules) == 0 {
return common.TargetHostnames(targetNetworkObject)
return common.TargetHostnames(targetNetworkObject), nil
}

uniqueHostnamesMap := make(map[string]any)
for idx := range ap.Spec.AuthRules {
if len(ap.Spec.AuthRules[idx].Hosts) == 0 {
// When one of the rules does not have hosts, just return target hostnames
return common.TargetHostnames(targetNetworkObject)
return common.TargetHostnames(targetNetworkObject), nil
}

for _, hostname := range ap.Spec.AuthRules[idx].Hosts {
Expand Down
5 changes: 1 addition & 4 deletions controllers/authpolicy_istio_authorization_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ func (r *AuthPolicyReconciler) reconcileIstioAuthorizationPolicies(ctx context.C
return err
}

targetHostnames, err := common.TargetHostnames(targetNetworkObject)
if err != nil {
return err
}
targetHostnames := common.TargetHostnames(targetNetworkObject)

// TODO(guicassolato): should the rules filter only the hostnames valid for each gateway?
toRules := istioAuthorizationPolicyRules(ap.Spec.AuthRules, targetHostnames, targetNetworkObject)
Expand Down
88 changes: 81 additions & 7 deletions controllers/rate_limiting_wasmplugin_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,29 +187,103 @@ func (r *RateLimitingWASMPluginReconciler) wasmPluginConfig(ctx context.Context,
return nil, err
}

rateLimitPolicies := gatewayAPITopology.GatewayPolicies()
rateLimitPolicies := gatewayAPITopology.PoliciesFromGateway(gw)

logger.V(1).Info("wasmPluginConfig", "#RLPS", len(rateLimitPolicies))

// TODO(eastizle): Sort RLPs by name for consistent comparison with existing objects??

for _, rlp := range rateLimitPolicies {
route := gatewayAPITopology.GetPolicyHTTPRoute(rlp)
wasmRLP := r.WASMRateLimitPolicy(gatewayAPITopology, rlp, gw)
if wasmRLP == nil {
// no need to add the policy if there are no rules;
// a rlp can return no rules if all its limits fail to match any route rule
continue
}

wasmPlugin.RateLimitPolicies = append(wasmPlugin.RateLimitPolicies, *wasmRLP)
}

return wasmPlugin, nil
}

func (r *RateLimitingWASMPluginReconciler) WASMRateLimitPolicy(t *common.KuadrantTopology, rlp *kuadrantv1beta2.RateLimitPolicy, gw *gatewayapiv1beta1.Gateway) []rlptools.Rule {
gwHostnames := common.TargetHostnames(gw)

route := r.RouteFromRLP(t, rlp, gw)

// narrow the list of hostnames specified in the route so we don't generate wasm rules that only apply to other gateways
// this is a no-op for the gateway rlp
hostnames := common.FilterValidSubdomains(gwHostnames, route.Spec.Hostnames)
if len(hostnames) == 0 { // it should only happen when the route specifies no hostnames
hostnames = gwHostnames
}

// gwHostnames := common.Map(gwHostnamesTmp, func(str string) gatewayapiv1beta1.Hostname { return gatewayapiv1beta1.Hostname(str) })

wasmRLP := &wasm.RateLimitPolicy{
Name: client.ObjectKeyFromObject(rlp).String(),
Domain: rlptools.LimitsNamespaceFromRLP(rlp),
Hostnames: common.HostnamesToStrings(hostnames), // we might be listing more hostnames than needed due to route selectors hostnames possibly being more restrictive
Service: common.KuadrantRateLimitClusterName,
Rules: nil,
}


}

// For gateway targeted policies, if no httproutes attached to the gateway, skip wasm config
func (r *RateLimitingWASMPluginReconciler) RouteFromRLP(t *common.KuadrantTopology, rlp *kuadrantv1beta2.RateLimitPolicy, gw *gatewayapiv1beta1.Gateway) *gatewayapiv1beta1.HTTPRoute {
route := t.GetPolicyHTTPRoute(rlp)

if route == nil {
// The policy is targeting a gateway
// This gateway policy will be enforced into all HTTPRoutes that do not have a policy attached to it

// Build imaginary route with all the routes not having a RLP targeting it
freeRoutes := t.GetFreeRoutes(gw)

// For policies targeting a gateway, when no httproutes is attached to the gateway, skip wasm config
// test wasm config when no http routes attached to the gateway
//logger.V(1).Info("no httproutes attached to the targeted gateway, skipping wasm config for the gateway rlp", "ratelimitpolicy", gwRLPKey)
freeRules := make([]gatewayapiv1beta1.HTTPRouteRule, 0)
for idx := range freeRoutes {
freeroute := freeRoutes[idx]
freeRules = append(freeRules, route.Spec.Rules...)
}
route = &gatewayapiv1beta1.HTTPRoute{
Spec: gatewayapiv1beta1.HTTPRouteSpec{
Hostnames: gwHostnames,
Rules: freeRules,
},
}
}

return route
}


if route == nil {
// policy targeting a gateway
// All the routes not having a RLP targeting it will be targeted by the
// Build imaginary route with all the routes not having a RLP targeting it

wasmRules := rlptools.WasmRules(rlp, route)
if len(wasmRules) == 0 {
// no need to add the policy if there are no rules;
// a rlp can return no rules if all its limits fail to match any route rule
continue
}

wasmPlugin.RateLimitPolicies = append(wasmPlugin.RateLimitPolicies, wasm.RateLimitPolicy{
Name: client.ObjectKeyFromObject(rlp).String(),
Domain: rlptools.LimitsNamespaceFromRLP(rlp),
Rules: wasmRules,
Hostnames: common.HostnamesToStrings(hostnames), // we might be listing more hostnames than needed due to route selectors hostnames possibly being more restrictive
Service: common.KuadrantRateLimitClusterName,
})

}

return wasmPlugin, nil
}


// SHOULD BE DELETED
func (r *RateLimitingWASMPluginReconciler) wasmPluginConfigTOBEDELETED(ctx context.Context, gw common.GatewayWrapper, rlpRefs []client.ObjectKey) (*wasm.Plugin, error) {
logger, _ := logr.FromContext(ctx)
Expand Down
9 changes: 3 additions & 6 deletions pkg/common/gatewayapi_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ func (g GatewayWrapperList) Swap(i, j int) {
}

// TargetHostnames returns an array of hostnames coming from the network object (HTTPRoute, Gateway)
func TargetHostnames(targetNetworkObject client.Object) ([]string, error) {
func TargetHostnames(targetNetworkObject client.Object) []string {
hosts := make([]string, 0)
switch obj := targetNetworkObject.(type) {
case *gatewayapiv1beta1.HTTPRoute:
Expand All @@ -546,15 +546,12 @@ func TargetHostnames(targetNetworkObject client.Object) ([]string, error) {
hosts = append(hosts, "*")
}

return hosts, nil
return hosts
}

// ValidateHierarchicalRules returns error if the policy rules hostnames fail to match the target network hosts
func ValidateHierarchicalRules(policy KuadrantPolicy, targetNetworkObject client.Object) error {
targetHostnames, err := TargetHostnames(targetNetworkObject)
if err != nil {
return err
}
targetHostnames := TargetHostnames(targetNetworkObject)

if valid, invalidHost := ValidSubdomains(targetHostnames, policy.GetRulesHostnames()); !valid {
return fmt.Errorf(
Expand Down
7 changes: 6 additions & 1 deletion pkg/common/kuadrant_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func NewKuadrantTopology(gateways []*gatewayapiv1beta1.Gateway, routes []*gatewa
return &KuadrantTopology{}
}

func (k *KuadrantTopology) GatewayPolicies() []KuadrantPolicy {
func (k *KuadrantTopology) PoliciesFromGateway(gateway *gatewayapiv1beta1.Gateway) []KuadrantPolicy {
// TODO
return nil
}
Expand All @@ -21,3 +21,8 @@ func (k *KuadrantTopology) GetPolicyHTTPRoute(policy KuadrantPolicy) *gatewayapi
// TODO
return nil
}

func (k *KuadrantTopology) GetFreeRoutes(gateway *gatewayapiv1beta1.Gateway) []*gatewayapiv1beta1.HTTPRoute {
// TODO
return nil
}

0 comments on commit a84fb4d

Please sign in to comment.