Skip to content

Commit

Permalink
new structure of the wasm config based on Kuadrant/wasm-shim#110
Browse files Browse the repository at this point in the history
Signed-off-by: Guilherme Cassolato <guicassolato@gmail.com>
  • Loading branch information
guicassolato committed Oct 16, 2024
1 parent 9d7bcd1 commit e3d5387
Show file tree
Hide file tree
Showing 10 changed files with 1,304 additions and 1,312 deletions.
14 changes: 7 additions & 7 deletions controllers/envoy_gateway_extenion_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (r *envoyGatewayExtensionReconciler) buildWasmConfigs(ctx context.Context,

logger.V(1).Info("building wasm configs for envoy gateway extension", "effectivePolicies", len(effectivePolicies.(EffectiveRateLimitPolicies)))

wasmPolicies := kuadrantgatewayapi.GrouppedHTTPRouteMatchConfigs{}
wasmActionSets := kuadrantgatewayapi.GrouppedHTTPRouteMatchConfigs{}

// build the wasm policies for each topological path that contains an effective rate limit policy affecting an envoy gateway gateway
for pathID, effectivePolicy := range effectivePolicies.(EffectiveRateLimitPolicies) {
Expand All @@ -152,17 +152,17 @@ func (r *envoyGatewayExtensionReconciler) buildWasmConfigs(ctx context.Context,
continue
}

wasmPoliciesForPath, err := wasm.BuildWasmPoliciesForPath(pathID, effectivePolicy.Path, effectivePolicy.Spec.Rules(), rateLimitWasmRuleBuilder(pathID, effectivePolicy, state))
wasmActionSetsForPath, err := wasm.BuildActionSetsForPath(pathID, effectivePolicy.Path, effectivePolicy.Spec.Rules(), rateLimitWasmActionBuilder(pathID, effectivePolicy, state))
if err != nil {
logger.Error(err, "failed to build wasm policies for path", "pathID", pathID)
continue
}
wasmPolicies.Add(gateway.GetLocator(), wasmPoliciesForPath...)
wasmActionSets.Add(gateway.GetLocator(), wasmActionSetsForPath...)
}

wasmConfigs := lo.MapValues(wasmPolicies.Sorted(), func(configs kuadrantgatewayapi.SortableHTTPRouteMatchConfigs, _ string) wasm.Config {
return wasm.BuildWasmConfigForPolicies(lo.Map(configs, func(c kuadrantgatewayapi.HTTPRouteMatchConfig, _ int) wasm.Policy {
return c.Config.(wasm.Policy)
wasmConfigs := lo.MapValues(wasmActionSets.Sorted(), func(configs kuadrantgatewayapi.SortableHTTPRouteMatchConfigs, _ string) wasm.Config {
return wasm.BuildConfigForActionSet(lo.Map(configs, func(c kuadrantgatewayapi.HTTPRouteMatchConfig, _ int) wasm.ActionSet {
return c.Config.(wasm.ActionSet)
}))
})

Expand Down Expand Up @@ -212,7 +212,7 @@ func buildEnvoyExtensionPolicyForGateway(gateway machinery.Targetable, wasmConfi
},
}

if len(wasmConfig.Policies) == 0 {
if len(wasmConfig.ActionSets) == 0 {
utils.TagObjectToDelete(envoyPolicy)
} else {
pluginConfigJSON, err := wasmConfig.ToJSON()
Expand Down
14 changes: 7 additions & 7 deletions controllers/istio_extension_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (r *istioExtensionReconciler) buildWasmConfigs(ctx context.Context, state *

logger.V(1).Info("building wasm configs for istio extension", "effectivePolicies", len(effectivePolicies.(EffectiveRateLimitPolicies)))

wasmPolicies := kuadrantgatewayapi.GrouppedHTTPRouteMatchConfigs{}
wasmActionSets := kuadrantgatewayapi.GrouppedHTTPRouteMatchConfigs{}

// build the wasm policies for each topological path that contains an effective rate limit policy affecting an istio gateway
for pathID, effectivePolicy := range effectivePolicies.(EffectiveRateLimitPolicies) {
Expand All @@ -153,17 +153,17 @@ func (r *istioExtensionReconciler) buildWasmConfigs(ctx context.Context, state *
continue
}

wasmPoliciesForPath, err := wasm.BuildWasmPoliciesForPath(pathID, effectivePolicy.Path, effectivePolicy.Spec.Rules(), rateLimitWasmRuleBuilder(pathID, effectivePolicy, state))
wasmActionSetsForPath, err := wasm.BuildActionSetsForPath(pathID, effectivePolicy.Path, effectivePolicy.Spec.Rules(), rateLimitWasmActionBuilder(pathID, effectivePolicy, state))
if err != nil {
logger.Error(err, "failed to build wasm policies for path", "pathID", pathID)
continue
}
wasmPolicies.Add(gateway.GetLocator(), wasmPoliciesForPath...)
wasmActionSets.Add(gateway.GetLocator(), wasmActionSetsForPath...)
}

wasmConfigs := lo.MapValues(wasmPolicies.Sorted(), func(configs kuadrantgatewayapi.SortableHTTPRouteMatchConfigs, _ string) wasm.Config {
return wasm.BuildWasmConfigForPolicies(lo.Map(configs, func(c kuadrantgatewayapi.HTTPRouteMatchConfig, _ int) wasm.Policy {
return c.Config.(wasm.Policy)
wasmConfigs := lo.MapValues(wasmActionSets.Sorted(), func(configs kuadrantgatewayapi.SortableHTTPRouteMatchConfigs, _ string) wasm.Config {
return wasm.BuildConfigForActionSet(lo.Map(configs, func(c kuadrantgatewayapi.HTTPRouteMatchConfig, _ int) wasm.ActionSet {
return c.Config.(wasm.ActionSet)
}))
})

Expand Down Expand Up @@ -195,7 +195,7 @@ func buildIstioWasmPluginForGateway(gateway machinery.Targetable, wasmConfig was
},
}

if len(wasmConfig.Policies) == 0 {
if len(wasmConfig.ActionSets) == 0 {
utils.TagObjectToDelete(wasmPlugin)
} else {
pluginConfigStruct, err := wasmConfig.ToStruct()
Expand Down
38 changes: 13 additions & 25 deletions controllers/ratelimit_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,51 +151,39 @@ func rateLimitClusterPatch(host string, port int) map[string]any {
}
}

func rateLimitWasmRuleBuilder(pathID string, effectivePolicy EffectiveRateLimitPolicy, state *sync.Map) wasm.RuleBuilderFunc {
func rateLimitWasmActionBuilder(pathID string, effectivePolicy EffectiveRateLimitPolicy, state *sync.Map) wasm.ActionBuilderFunc {
policiesInPath := kuadrantv1.PoliciesInPath(effectivePolicy.Path, isRateLimitPolicyAcceptedAndNotDeletedFunc(state))

// assumes the path is always [gatewayclass, gateway, listener, httproute, httprouterule]
httpRoute, _ := effectivePolicy.Path[3].(*machinery.HTTPRoute)

limitsNamespace := LimitsNamespaceFromRoute(httpRoute.HTTPRoute)

return func(httpRouteMatch gatewayapiv1.HTTPRouteMatch, uniquePolicyRuleKey string, policyRule kuadrantv1.MergeableRule) (wasm.Rule, error) {
return func(uniquePolicyRuleKey string, policyRule kuadrantv1.MergeableRule) (wasm.Action, error) {
source, found := lo.Find(policiesInPath, func(p machinery.Policy) bool {
return p.GetLocator() == policyRule.Source
})
if !found { // should never happen
return wasm.Rule{}, fmt.Errorf("could not find source policy %s in path %s", policyRule.Source, pathID)
return wasm.Action{}, fmt.Errorf("could not find source policy %s in path %s", policyRule.Source, pathID)
}
limitIdentifier := LimitNameToLimitadorIdentifier(k8stypes.NamespacedName{Name: source.GetName(), Namespace: source.GetNamespace()}, uniquePolicyRuleKey)
limit := policyRule.Spec.(kuadrantv1beta3.Limit)
return wasmRuleFromLimit(limit, limitIdentifier, limitsNamespace, httpRouteMatch), nil
return wasmActionFromLimit(limit, limitIdentifier, limitsNamespace), nil
}
}

// wasmRuleFromLimit builds a wasm rate-limit rule for a given limit.
// Conditions are built from the limit top-level conditions and a HTTPRouteMatch.
// The order of the conditions is as follows:
// 1. Route-level conditions: HTTP method, path, headers
// 2. Top-level conditions: 'when' conditions (blended into each block of route-level conditions)
// wasmActionFromLimit builds a wasm rate-limit action for a given limit.
// Conditions are built from the limit top-level conditions.
//
// The only action of the rule is the rate-limit policy extension, whose data includes the activation of the limit
// The only action of the rule is the ratelimit service, whose data includes the activation of the limit
// and any counter qualifier of the limit.
func wasmRuleFromLimit(limit kuadrantv1beta3.Limit, limitIdentifier, scope string, routeMatch gatewayapiv1.HTTPRouteMatch) wasm.Rule {
rule := wasm.Rule{
Conditions: wasm.ConditionsFromHTTPRouteMatch(routeMatch, limit.When...),
func wasmActionFromLimit(limit kuadrantv1beta3.Limit, limitIdentifier, scope string) wasm.Action {
return wasm.Action{
ServiceName: wasm.RateLimitServiceName,
Scope: scope,
Conditions: wasm.PredicatesFromWhenConditions(limit.When...),
Data: wasmDataFromLimit(limitIdentifier, limit),
}

if data := wasmDataFromLimit(limitIdentifier, limit); data != nil {
rule.Actions = []wasm.Action{
{
Scope: scope,
ExtensionName: wasm.RateLimitExtensionName,
Data: data,
},
}
}

return rule
}

func wasmDataFromLimit(limitIdentifier string, limit kuadrantv1beta3.Limit) (data []wasm.DataType) {
Expand Down
Loading

0 comments on commit e3d5387

Please sign in to comment.