Skip to content

Commit

Permalink
Merge pull request #2483 from AmaliMatharaarachchi/main-sync-r2
Browse files Browse the repository at this point in the history
Add enforcer api filter flow
  • Loading branch information
AmaliMatharaarachchi authored Sep 23, 2024
2 parents a131838 + 688c633 commit a90635e
Show file tree
Hide file tree
Showing 46 changed files with 865 additions and 291 deletions.
1 change: 1 addition & 0 deletions adapter/api/proto/wso2/discovery/api/Resource.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ message Operation {
string tier = 3;
OperationPolicies policies = 4;
repeated string scopes = 5;
string matchID = 6;
// MockedApiConfig mockedApiConfig = 6;
}

Expand Down
1 change: 1 addition & 0 deletions adapter/api/proto/wso2/discovery/api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ message Api {
string mutualSSL = 15;
map<string, bool> applicationSecurity = 16;
bool transportSecurity = 17;
repeated string httpRouteIDs = 19;
/// string graphQLSchema = 22;
repeated GraphqlComplexity graphqlComplexityInfo = 23;
bool systemAPI = 24;
Expand Down
2 changes: 2 additions & 0 deletions adapter/api/proto/wso2/discovery/config/enforcer/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ message Config {

bool mandateInternalKeyValidation = 15;

bool enableGatewayClassController = 16;

}
2 changes: 2 additions & 0 deletions adapter/config/default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ var defaultConfig = &Config{
CommonControllerXDSPort: "18002",
CommonControllerRestPort: "18003",
EnforcerLabel: "wso2-apk-default",
EnforcerImage: "wso2/apk-enforcer:1.1.0",
EnforcerImagePullPolicy: "Always",
EnforcerRegion: "UNKNOWN",
EnforcerXDSMaxMsgSize: "4194304",
EnforcerXDSMaxRetries: "3",
Expand Down
2 changes: 2 additions & 0 deletions adapter/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ type gateway struct {
CommonControllerRestPort string
EnforcerLabel string
EnforcerRegion string
EnforcerImage string
EnforcerImagePullPolicy string
EnforcerXDSMaxMsgSize string
EnforcerXDSMaxRetries string
JavaOpts string
Expand Down
2 changes: 2 additions & 0 deletions adapter/internal/discovery/xds/marshaller.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func MarshalConfig(config *config.Config) *enforcer.Config {
}
mandateSubscriptionValidation := config.Enforcer.MandateSubscriptionValidation
mandateInternalKeyValidation := config.Enforcer.MandateInternalKeyValidation
enableGatewayClassController := config.Adapter.EnableGatewayClassController

analytics := &enforcer.Analytics{
Enabled: config.Analytics.Enabled,
Expand Down Expand Up @@ -160,6 +161,7 @@ func MarshalConfig(config *config.Config) *enforcer.Config {
Soap: soap,
MandateSubscriptionValidation: mandateSubscriptionValidation,
MandateInternalKeyValidation: mandateInternalKeyValidation,
EnableGatewayClassController: enableGatewayClassController,
HttpClient: httpClient,
}
}
Expand Down
2 changes: 2 additions & 0 deletions adapter/internal/oasparser/config_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ func GetEnforcerAPI(adapterInternalAPI *model.AdapterInternalAPI, vhost string)
}
return nil
}(),
HttpRouteIDs: adapterInternalAPI.HTTPRouteIDs,
}
}

Expand All @@ -269,6 +270,7 @@ func GetEnforcerAPIOperation(operation model.Operation, isMockedAPI bool) *api.O
ApiAuthentication: castAPIAuthenticationsToEnforcerAPIAuthentications(operation.GetAuthentication()),
Tier: operation.GetTier(),
Policies: policies,
MatchID: operation.GetMatchID(),
// MockedApiConfig: mockedAPIConfig,
}
return &apiOperation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestCreateRoute(t *testing.T) {
})

resourceWithGet := model.CreateMinimalDummyResourceForTests("/xWso2BasePath/resourcePath",
[]*model.Operation{model.NewOperationWithPolicies("GET", policies)},
[]*model.Operation{model.NewOperationWithPolicies("GET", policies, "")},
"resource_operation_id", []model.Endpoint{endpoint}, true, false)
clusterName := "resource_operation_id"
hostRewriteSpecifier := &routev3.RouteAction_AutoHostRewrite{
Expand Down Expand Up @@ -142,7 +142,7 @@ func TestCreateRouteClusterSpecifier(t *testing.T) {
Port: 80,
RawURL: "http://abc.com",
}
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil)},
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil, "")},
"resource_operation_id", []model.Endpoint{endpoint}, false, false)

route, err := createRoutes(generateRouteCreateParamsForUnitTests(title, apiType, vHost, xWso2BasePath, version, endpointBasePath,
Expand Down Expand Up @@ -173,7 +173,7 @@ func TestCreateRouteExtAuthzContext(t *testing.T) {
Port: 80,
RawURL: "http://abc.com",
}
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil)},
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil, "")},
"resource_operation_id", []model.Endpoint{endpoint}, false, false)

route, err := createRoutes(generateRouteCreateParamsForUnitTests(title, apiType, vHost, xWso2BasePath, version,
Expand Down Expand Up @@ -570,7 +570,7 @@ func TestGetCorsPolicy(t *testing.T) {
"Cors Allowed Origin Header mismatch")
assert.Empty(t, corsPolicy3.GetAllowCredentials(), "Allow Credential property should not be assigned.")

resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil)},
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{model.NewOperation("GET", nil, nil, "")},
"resource_operation_id", []model.Endpoint{endpoint}, false, false)

// Route without CORS configuration
Expand Down
6 changes: 3 additions & 3 deletions adapter/internal/oasparser/envoyconf/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ func testCreateRoutesForUnitTests(t *testing.T) []*routev3.Route {
RawURL: "http://abc.com",
}

operationGet := model.NewOperation("GET", nil, nil)
operationPost := model.NewOperation("POST", nil, nil)
operationPut := model.NewOperation("PUT", nil, nil)
operationGet := model.NewOperation("GET", nil, nil, "")
operationPost := model.NewOperation("POST", nil, nil, "")
operationPut := model.NewOperation("PUT", nil, nil, "")
resourceWithGet := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{operationGet},
"resource_operation_id", []model.Endpoint{endpoint}, false, false)
resourceWithPost := model.CreateMinimalDummyResourceForTests("/resourcePath", []*model.Operation{operationPost},
Expand Down
4 changes: 2 additions & 2 deletions adapter/internal/oasparser/envoyconf/routes_with_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func CreateRoutesWithClusters(adapterInternalAPI *model.AdapterInternalAPI, inte
},
},
}
gqlop := model.NewOperationWithPolicies("POST", policies)
gqlop := model.NewOperationWithPolicies("POST", policies, "")
resource := model.CreateMinimalResource(adapterInternalAPI.GetXWso2Basepath(), []*model.Operation{gqlop}, "", adapterInternalAPI.Endpoints, true, false, gwapiv1.PathMatchExact)
routesP, err := createRoutes(genRouteCreateParams(adapterInternalAPI, &resource, vHost, basePath, clusterName, nil,
nil, organizationID, false, false, nil))
Expand Down Expand Up @@ -930,7 +930,7 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error
}
}
if !hasOptions {
operations = append(operations, model.NewOperation("OPTIONS", nil, nil))
operations = append(operations, model.NewOperation("OPTIONS", nil, nil, ""))
}
}

Expand Down
13 changes: 9 additions & 4 deletions adapter/internal/oasparser/model/adapter_internal_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ type AdapterInternalAPI struct {
Endpoints *EndpointCluster
EndpointSecurity []*EndpointSecurity
AIProvider InternalAIProvider
HTTPRouteIDs []string
}

// BackendJWTTokenInfo represents the object structure holding the information related to the JWT Generator
Expand Down Expand Up @@ -523,7 +524,7 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap
ratelimitPolicy = *outputRatelimitPolicy
}

for _, rule := range httpRoute.Spec.Rules {
for ruleID, rule := range httpRoute.Spec.Rules {
var endPoints []Endpoint
var policies = OperationPolicies{}
var circuitBreaker *dpv1alpha2.CircuitBreaker
Expand Down Expand Up @@ -878,7 +879,11 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap
loggers.LoggerOasparser.Debugf("Calculating auths for API ..., API_UUID = %v", adapterInternalAPI.UUID)
apiAuth := getSecurity(resourceAuthScheme)

for _, match := range rule.Matches {
if !hasRequestRedirectPolicy && len(rule.BackendRefs) < 1 {
return fmt.Errorf("no backendref were provided")
}

for matchID, match := range rule.Matches {
if hasURLRewritePolicy && hasRequestRedirectPolicy {
return fmt.Errorf("cannot have URL Rewrite and Request Redirect under the same rule")
}
Expand All @@ -898,8 +903,8 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap
})
}
resourcePath := adapterInternalAPI.xWso2Basepath + *match.Path.Value

operations := getAllowedOperations(match.Method, policies, apiAuth,
matchID := getMatchID(httpRoute.Namespace, httpRoute.Name, ruleID, matchID)
operations := getAllowedOperations(matchID, match.Method, policies, apiAuth,
parseRateLimitPolicyToInternal(resourceRatelimitPolicy), scopes, mirrorEndpointClusters)
resource := &Resource{path: resourcePath,
methods: operations,
Expand Down
13 changes: 9 additions & 4 deletions adapter/internal/oasparser/model/api_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Operation struct {
mockedAPIConfig *api.MockedApiConfig
rateLimitPolicy *RateLimitPolicy
mirrorEndpointClusters []*EndpointCluster
matchID string
}

// Authentication holds authentication related configurations
Expand Down Expand Up @@ -109,6 +110,10 @@ func (operation *Operation) GetTier() string {
return operation.tier
}

func (operation *Operation) GetMatchID() string {
return operation.matchID
}

// GetMockedAPIConfig returns the operation level mocked API implementation configs
func (operation *Operation) GetMockedAPIConfig() *api.MockedApiConfig {
return operation.mockedAPIConfig
Expand Down Expand Up @@ -176,14 +181,14 @@ func (operation *Operation) GetCallInterceptorService(isIn bool) InterceptEndpoi
}

// NewOperation Creates and returns operation type object
func NewOperation(method string, security []string, extensions map[string]interface{}) *Operation {
func NewOperation(method string, security []string, extensions map[string]interface{}, matchID string) *Operation {
tier := ResolveThrottlingTier(extensions)
disableSecurity := ResolveDisableSecurity(extensions)
id := uuid.New().String()
return &Operation{id, method, security, nil, tier, disableSecurity, extensions, OperationPolicies{}, &api.MockedApiConfig{}, nil, nil}
return &Operation{id, method, security, nil, tier, disableSecurity, extensions, OperationPolicies{}, &api.MockedApiConfig{}, nil, nil, matchID}
}

// NewOperationWithPolicies Creates and returns operation with given method and policies
func NewOperationWithPolicies(method string, policies OperationPolicies) *Operation {
return &Operation{iD: uuid.New().String(), method: method, policies: policies}
func NewOperationWithPolicies(method string, policies OperationPolicies, matchID string) *Operation {
return &Operation{iD: uuid.New().String(), method: method, policies: policies, matchID: matchID}
}
9 changes: 9 additions & 0 deletions adapter/internal/oasparser/model/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package model

import (
"errors"
"fmt"
"net/url"
"regexp"
"strconv"
Expand Down Expand Up @@ -155,3 +156,11 @@ func getHostandBasepathandPort(apiType string, rawURL string) (*Endpoint, error)

return &Endpoint{Host: host, Basepath: basepath, Port: port, URLType: urlType, RawURL: rawURL}, nil
}

func getRouteID(namespace, name string) string {
return fmt.Sprintf("httproute/%s/%s/", namespace, name)
}

func getMatchID(namespace, name string, ruleID, matchID int) string {
return fmt.Sprintf("%srule/%d/match/%d", getRouteID(namespace, name), ruleID, matchID)
}
30 changes: 21 additions & 9 deletions adapter/internal/oasparser/model/http_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,26 +287,26 @@ func getSecurity(authScheme *dpv1alpha2.Authentication) *Authentication {
}

// getAllowedOperations retuns a list of allowed operatons, if httpMethod is not specified then all methods are allowed.
func getAllowedOperations(httpMethod *gwapiv1.HTTPMethod, policies OperationPolicies, auth *Authentication,
func getAllowedOperations(matchID string, httpMethod *gwapiv1.HTTPMethod, policies OperationPolicies, auth *Authentication,
ratelimitPolicy *RateLimitPolicy, scopes []string, mirrorEndpointClusters []*EndpointCluster) []*Operation {
if httpMethod != nil {
return []*Operation{{iD: uuid.New().String(), method: string(*httpMethod), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters}}
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID}}
}
return []*Operation{{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodGet), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodPost), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodDelete), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodPatch), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodPut), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodHead), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters},
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID},
{iD: uuid.New().String(), method: string(gwapiv1.HTTPMethodOptions), policies: policies,
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters}}
auth: auth, rateLimitPolicy: ratelimitPolicy, scopes: scopes, mirrorEndpointClusters: mirrorEndpointClusters, matchID: matchID}}
}

// SetInfoAPICR populates ID, ApiType, Version and XWso2BasePath of adapterInternalAPI.
Expand All @@ -319,4 +319,16 @@ func (swagger *AdapterInternalAPI) SetInfoAPICR(api dpv1alpha2.API) {
swagger.OrganizationID = api.Spec.Organization
swagger.IsSystemAPI = api.Spec.SystemAPI
swagger.APIProperties = api.Spec.APIProperties
httpRouteIDs := []string{}
for _, route := range api.Spec.Production {
for _, routeRef := range route.RouteRefs {
httpRouteIDs = append(httpRouteIDs, getRouteID(api.Namespace, routeRef))
}
}
for _, route := range api.Spec.Sandbox {
for _, routeRef := range route.RouteRefs {
httpRouteIDs = append(httpRouteIDs, getRouteID(api.Namespace, routeRef))
}
}
swagger.HTTPRouteIDs = httpRouteIDs
}
2 changes: 1 addition & 1 deletion adapter/internal/operator/controllers/dp/api_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,7 @@ func (apiReconciler *APIReconciler) getAPIsForSecret(ctx context.Context, obj k8
if err := apiReconciler.client.List(ctx, backendList, &k8client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(secretBackend, utils.NamespacedName(secret).String()),
}); err != nil {
loggers.LoggerAPKOperator.ErrorC(logging.PrintError(logging.Error2621, logging.MINOR, "Unable to find associated Backends for Secret: %s", utils.NamespacedName(secret).String()))
loggers.LoggerAPKOperator.Debugf("Unable to find associated Backends for Secret: %s", utils.NamespacedName(secret).String())
return []reconcile.Request{}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
},
},
{
Name: enforcerContainerName,
Image: *deploymentConfig.EnforcerContainer.Image,
ImagePullPolicy: corev1.PullIfNotPresent,
// Command: []string{"envoy"},
// Args: args,
Name: enforcerContainerName,
Image: *deploymentConfig.EnforcerContainer.Image,
ImagePullPolicy: corev1.PullPolicy(config.ReadConfigs().Deployment.Gateway.EnforcerImagePullPolicy),
Env: expectedEnforcerEnv(deploymentConfig.EnforcerContainer),
Resources: *deploymentConfig.EnforcerContainer.Resources,
SecurityContext: deploymentConfig.EnforcerContainer.SecurityContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,15 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
}

for _, port := range config.ReadConfigs().Deployment.Gateway.EnforcerPorts {
p := corev1.ServicePort{
Name: ExpectedResourceHashedName(port.Name),
Protocol: corev1.ProtocolTCP,
Port: port.ContainerPort,
TargetPort: intstr.IntOrString{IntVal: port.ContainerPort},
if port.Expose {
p := corev1.ServicePort{
Name: ExpectedResourceHashedName(port.Name),
Protocol: corev1.ProtocolTCP,
Port: port.ContainerPort,
TargetPort: intstr.IntOrString{IntVal: port.ContainerPort},
}
ports = append(ports, p)
}
ports = append(ports, p)
}

// Set the labels based on the owning gatewayclass name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,17 @@ func (r *gatewayReconcilerNew) processHTTPRoutes(ctx context.Context, gatewayNam
newMatches = append(newMatches, match)
}
rule.Matches = newMatches
rule.Filters = append(rule.Filters,
gwapiv1.HTTPRouteFilter{
Type: gwapiv1.HTTPRouteFilterURLRewrite,
URLRewrite: &gwapiv1.HTTPURLRewriteFilter{
Path: &gwapiv1.HTTPPathModifier{
Type: gwapiv1.PrefixMatchHTTPPathModifier,
ReplacePrefixMatch: &api.Spec.BasePath,
},
},
},
)
newRules = append(newRules, rule)
}
hr.Spec.Rules = newRules
Expand Down
5 changes: 1 addition & 4 deletions adapter/internal/operator/gateway-api/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -1097,16 +1097,14 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
if backendRef.Weight != nil {
weight = uint32(*backendRef.Weight)
}
loggers.LoggerAPI.Error("amalii", backendRef)

backendNamespace := NamespaceDerefOr(backendRef.Namespace, route.GetNamespace())
if !t.validateBackendRef(backendRefContext, parentRef, route, resources, backendNamespace, routeType) {
loggers.LoggerAPI.Error("amalii")
return nil, weight
}

// Skip processing backends with 0 weight
if weight == 0 {
loggers.LoggerAPI.Error("amalii")
return nil, weight
}

Expand Down Expand Up @@ -1145,7 +1143,6 @@ func (t *Translator) processDestination(backendRefContext BackendRefContext,
endpoints = append(endpoints, ep)
}
case KindBackend:
loggers.LoggerAPI.Error("amalii")
backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
ep := ir.NewDestEndpoint(
backend.Spec.Services[0].Host,
Expand Down
Loading

0 comments on commit a90635e

Please sign in to comment.