From ac7873bfce96e25c831e51b6acd5110f6952da2c Mon Sep 17 00:00:00 2001 From: Krishanx92 Date: Wed, 14 Aug 2024 22:08:08 +0530 Subject: [PATCH] Header base route support --- .../oasparser/envoyconf/routes_configs.go | 18 ++++++++++ .../envoyconf/routes_with_clusters.go | 13 +++++++ .../oasparser/model/adapter_internal_api.go | 35 +++++++++++++++---- adapter/internal/oasparser/model/resource.go | 18 ++++++++++ 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/adapter/internal/oasparser/envoyconf/routes_configs.go b/adapter/internal/oasparser/envoyconf/routes_configs.go index 585ab47ba..b258cba34 100644 --- a/adapter/internal/oasparser/envoyconf/routes_configs.go +++ b/adapter/internal/oasparser/envoyconf/routes_configs.go @@ -232,6 +232,11 @@ func generateHTTPMethodMatcher(methodRegex string, sandClusterName string) []*ro return headerMatcherArray } +func generateHTTPMethodExactMatcher(headername, value string) *routev3.HeaderMatcher { + headerMatcher := generateHeaderExactMatch(headername, value) + return headerMatcher +} + func generateQueryParamMatcher(queryParamName, value string) []*routev3.QueryParameterMatcher { queryParamMatcher := &routev3.QueryParameterMatcher{ Name: queryParamName, @@ -263,6 +268,19 @@ func generateHeaderMatcher(headerName, valueRegex string) *routev3.HeaderMatcher return headerMatcherArray } +func generateHeaderExactMatch(headerName, value string) *routev3.HeaderMatcher { + if len(headerName) == 0 { + return nil + } + headerMatcherArray := &routev3.HeaderMatcher{ + Name: headerName, + HeaderMatchSpecifier: &routev3.HeaderMatcher_ExactMatch{ + ExactMatch: value, + }, + } + return headerMatcherArray +} + func generateRegexMatchAndSubstitute(routePath, endpointResourcePath string, pathMatchType gwapiv1.PathMatchType) *envoy_type_matcherv3.RegexMatchAndSubstitute { substitutionString := generateSubstitutionString(endpointResourcePath, pathMatchType) diff --git a/adapter/internal/oasparser/envoyconf/routes_with_clusters.go b/adapter/internal/oasparser/envoyconf/routes_with_clusters.go index 85f673c38..7e165aa37 100644 --- a/adapter/internal/oasparser/envoyconf/routes_with_clusters.go +++ b/adapter/internal/oasparser/envoyconf/routes_with_clusters.go @@ -756,6 +756,9 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error resourceMethods := resource.GetMethodList() pathMatchType := resource.GetPathMatchType() + headerKey := resource.GetKey() + headerValue := resource.GetValue() + contextExtensions := make(map[string]string) contextExtensions[pathContextExtension] = resourcePath contextExtensions[vHostContextExtension] = vHost @@ -1079,7 +1082,14 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error logger.LoggerOasparser.Debug("Creating routes for resource with policies", resourcePath, operation.GetMethod()) // create route for current method. Add policies to route config. Send via enforcer match := generateRouteMatch(routePath) + logger.LoggerAPK.Info("Header key: ", headerKey) + logger.LoggerAPK.Info("Header value: ", headerValue) match.Headers = generateHTTPMethodMatcher(operation.GetMethod(), clusterName) + if headerKey != "" && headerValue != "" { + match.Headers = append(match.Headers, generateHTTPMethodExactMatcher(string(headerKey), headerValue)) + } + //match.Headers = append(match.Headers, generateHeaderMatcher(string(headerKey), headerValue)) + logger.LoggerAPK.Info("Header keyx: ") match.DynamicMetadata = generateMetadataMatcherForExternalRoutes() if pathRewriteConfig != nil && requestRedirectAction == nil { action.Route.RegexRewrite = pathRewriteConfig @@ -1100,6 +1110,9 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error } match := generateRouteMatch(routePath) match.Headers = generateHTTPMethodMatcher(methodRegex, clusterName) + if headerKey != "" && headerValue != "" { + match.Headers = append(match.Headers, generateHTTPMethodExactMatcher(string(headerKey), headerValue)) + } action := generateRouteAction(apiType, routeConfig, rateLimitPolicyCriteria, nil) rewritePath := generateRoutePathForReWrite(basePath, resourcePath, pathMatchType) action.Route.RegexRewrite = generateRegexMatchAndSubstitute(rewritePath, resourcePath, pathMatchType) diff --git a/adapter/internal/oasparser/model/adapter_internal_api.go b/adapter/internal/oasparser/model/adapter_internal_api.go index 0487432fd..e1ae371f1 100644 --- a/adapter/internal/oasparser/model/adapter_internal_api.go +++ b/adapter/internal/oasparser/model/adapter_internal_api.go @@ -836,12 +836,32 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap operations := getAllowedOperations(match.Method, policies, apiAuth, parseRateLimitPolicyToInternal(resourceRatelimitPolicy), scopes, mirrorEndpointClusters) - resource := &Resource{path: resourcePath, - methods: operations, - pathMatchType: *match.Path.Type, - hasPolicies: true, - iD: uuid.New().String(), - hasRequestRedirectFilter: hasRequestRedirectPolicy, + var resource *Resource + if match.Headers != nil && len(match.Headers) > 0 { + for _, header := range match.Headers { + loggers.LoggerAPI.Info("Inside Header Match") + loggers.LoggerAPI.Info("Header Name: ", header.Name) + loggers.LoggerAPI.Info("Header Value: ", header.Value) + resource = &Resource{path: resourcePath, + methods: operations, + pathMatchType: *match.Path.Type, + headerMatchType: *header.Type, + key: header.Name, + value: header.Value, + hasPolicies: true, + iD: uuid.New().String(), + hasRequestRedirectFilter: hasRequestRedirectPolicy, + } + } + } else { + loggers.LoggerAPI.Info("Inside Not Header Match") + resource = &Resource{path: resourcePath, + methods: operations, + pathMatchType: *match.Path.Type, + hasPolicies: true, + iD: uuid.New().String(), + hasRequestRedirectFilter: hasRequestRedirectPolicy, + } } resource.endpoints = &EndpointCluster{ @@ -882,7 +902,10 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoHTTPRouteCR(httpRoute *gwap resource.endpoints.Config = endpointConfig } resource.endpointSecurity = utils.GetPtrSlice(securityConfig) + loggers.LoggerAPI.Info("Resource Key: ", resource.GetKey()) + loggers.LoggerAPI.Info("Resource Value: ", resource.GetValue()) resources = append(resources, resource) + } } diff --git a/adapter/internal/oasparser/model/resource.go b/adapter/internal/oasparser/model/resource.go index 9fafd7f87..28485a431 100644 --- a/adapter/internal/oasparser/model/resource.go +++ b/adapter/internal/oasparser/model/resource.go @@ -39,6 +39,9 @@ type Resource struct { path string pathMatchType gwapiv1.PathMatchType methods []*Operation + headerMatchType gwapiv1.HeaderMatchType + key gwapiv1.HTTPHeaderName + value string iD string endpoints *EndpointCluster endpointSecurity []*EndpointSecurity @@ -47,6 +50,21 @@ type Resource struct { hasRequestRedirectFilter bool } +// GetHeaderMatchType returns the header match type of the resource. +func (resource *Resource) GetHeaderMatchType() gwapiv1.HeaderMatchType { + return resource.headerMatchType +} + +// GetKey returns the key of the resource. +func (resource *Resource) GetKey() gwapiv1.HTTPHeaderName { + return resource.key +} + +// GetValue returns the value of the resource. +func (resource *Resource) GetValue() string { + return resource.value +} + // GetEndpointSecurity returns the endpoint security object of a given resource. func (resource *Resource) GetEndpointSecurity() []*EndpointSecurity { return resource.endpointSecurity