Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions apidef/api_definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ type ExtendedPathsSet struct {
CircuitBreaker []CircuitBreakerMeta `bson:"circuit_breakers" json:"circuit_breakers,omitempty"`
URLRewrite []URLRewriteMeta `bson:"url_rewrites" json:"url_rewrites,omitempty"`
Virtual []VirtualMeta `bson:"virtual" json:"virtual,omitempty"`
AWSLambda []AWSLambdaMeta `bson:"aws_lambda" json:"aws_lambda,omitempty"`
SizeLimit []RequestSizeMeta `bson:"size_limits" json:"size_limits,omitempty"`
MethodTransforms []MethodTransformMeta `bson:"method_transforms" json:"method_transforms,omitempty"`
TrackEndpoints []TrackEndpointMeta `bson:"track_endpoints" json:"track_endpoints,omitempty"`
Expand All @@ -427,6 +428,56 @@ func (e *ExtendedPathsSet) Clear() {
}
}

// AWSLambdaMeta defines per-path AWS Lambda invocation configuration.
type AWSLambdaMeta struct {
Disabled bool `bson:"disabled" json:"disabled"`
Path string `bson:"path" json:"path"`
Method string `bson:"method" json:"method"`
FunctionName string `bson:"function_name" json:"function_name"`
Qualifier string `bson:"qualifier" json:"qualifier,omitempty"`
Region string `bson:"region" json:"region"`
InvocationType string `bson:"invocation_type" json:"invocation_type"`
TimeoutMs int `bson:"timeout_ms" json:"timeout_ms"`

Credentials AWSCredentialsConfig `bson:"credentials" json:"credentials"`
RequestMapping AWSLambdaRequestMapping `bson:"request_mapping" json:"request_mapping"`
ResponseMapping AWSLambdaResponseMapping `bson:"response_mapping" json:"response_mapping"`
}

// AWSCredentialsConfig configures how credentials are resolved for Lambda invocation.
type AWSCredentialsConfig struct {
UseSDKDefaultChain bool `bson:"use_sdk_default_chain" json:"use_sdk_default_chain"`
AccessKeyID string `bson:"access_key_id" json:"access_key_id,omitempty"`
SecretAccessKey string `bson:"secret_access_key" json:"secret_access_key,omitempty"`
SessionToken string `bson:"session_token" json:"session_token,omitempty"`
AssumeRoleARN string `bson:"assume_role_arn" json:"assume_role_arn,omitempty"`
ExternalID string `bson:"external_id" json:"external_id,omitempty"`
EndpointOverride string `bson:"endpoint_override" json:"endpoint_override,omitempty"`
}

// AWSLambdaRequestMapping controls how HTTP requests are converted into Lambda payloads.
type AWSLambdaRequestMapping struct {
Mode string `bson:"mode" json:"mode"`
ForwardBody bool `bson:"forward_body" json:"forward_body"`
ForwardHeaders bool `bson:"forward_headers" json:"forward_headers"`
ForwardQuerystring bool `bson:"forward_querystrings" json:"forward_querystrings"`
ForwardPath bool `bson:"forward_path" json:"forward_path"`
PayloadVersion string `bson:"payload_version" json:"payload_version"`
Base64EncodeBody bool `bson:"base64_encode_body" json:"base64_encode_body"`
HeaderAllowList []string `bson:"header_allow_list" json:"header_allow_list,omitempty"`
QueryAllowList []string `bson:"query_allow_list" json:"query_allow_list,omitempty"`
}

// AWSLambdaResponseMapping controls how Lambda responses are mapped to HTTP responses.
type AWSLambdaResponseMapping struct {
Mode string `bson:"mode" json:"mode"`
DefaultStatus int `bson:"default_status" json:"default_status"`
ErrorStatus int `bson:"error_status" json:"error_status"`
DecodeBase64Body bool `bson:"decode_base64_body" json:"decode_base64_body"`
UnhandledStatus int `bson:"unhandled_status" json:"unhandled_status"`
HeaderPassthrough bool `bson:"header_passthrough" json:"header_passthrough"`
}

// VersionDefinition is a struct that holds the versioning information for an API.
type VersionDefinition struct {
// Enabled indicates whether this version is enabled or not.
Expand Down
53 changes: 39 additions & 14 deletions gateway/api_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,10 @@ const (
RequestNotTracked
ValidateJSONRequest
Internal
GoPlugin
PersistGraphQL
RateLimit
GoPlugin
PersistGraphQL
RateLimit
AWSLambda
)

// RequestStatus is a custom type to avoid collisions
Expand Down Expand Up @@ -121,8 +122,9 @@ const (
StatusValidateRequest RequestStatus = "Validate Request"
StatusInternal RequestStatus = "Internal path"
StatusGoPlugin RequestStatus = "Go plugin"
StatusPersistGraphQL RequestStatus = "Persist GraphQL"
StatusRateLimit RequestStatus = "Rate Limited"
StatusPersistGraphQL RequestStatus = "Persist GraphQL"
StatusRateLimit RequestStatus = "Rate Limited"
StatusAWSLambda RequestStatus = "AWS Lambda"
)

type EndPointCacheMeta struct {
Expand Down Expand Up @@ -1147,6 +1149,25 @@ func (a APIDefinitionLoader) compileVirtualPathsSpec(paths []apidef.VirtualMeta,
return urlSpec
}

func (a APIDefinitionLoader) compileAWSLambdaPathSpec(paths []apidef.AWSLambdaMeta, stat URLStatus, _ *APISpec, conf config.Config) []URLSpec {
// transform an extended configuration URL into an array of URLSpecs
// This way we can iterate the whole array once, on match we break with status
urlSpec := []URLSpec{}
for _, stringSpec := range paths {
if stringSpec.Disabled {
continue
}

newSpec := URLSpec{}
a.generateRegex(stringSpec.Path, &newSpec, stat, conf)
newSpec.AWSLambda = stringSpec

urlSpec = append(urlSpec, newSpec)
}

return urlSpec
}

func (a APIDefinitionLoader) compileGopluginPathsSpec(paths []apidef.GoPluginMeta, stat URLStatus, _ *APISpec, conf config.Config) []URLSpec {

// transform an extended configuration URL into an array of URLSpecs
Expand Down Expand Up @@ -1318,7 +1339,8 @@ func (a APIDefinitionLoader) getExtendedPathSpecs(apiVersionDef apidef.VersionIn
unTrackedPaths := a.compileUnTrackedEndpointPathsSpec(apiVersionDef.ExtendedPaths.DoNotTrackEndpoints, RequestNotTracked, conf)
validateJSON := a.compileValidateJSONPathsSpec(apiVersionDef.ExtendedPaths.ValidateJSON, ValidateJSONRequest, conf)
internalPaths := a.compileInternalPathsSpec(apiVersionDef.ExtendedPaths.Internal, Internal, conf)
goPlugins := a.compileGopluginPathsSpec(apiVersionDef.ExtendedPaths.GoPlugin, GoPlugin, apiSpec, conf)
goPlugins := a.compileGopluginPathsSpec(apiVersionDef.ExtendedPaths.GoPlugin, GoPlugin, apiSpec, conf)
lambdaPaths := a.compileAWSLambdaPathSpec(apiVersionDef.ExtendedPaths.AWSLambda, AWSLambda, apiSpec, conf)
persistGraphQL := a.compilePersistGraphQLPathSpec(apiVersionDef.ExtendedPaths.PersistGraphQL, PersistGraphQL, apiSpec, conf)
rateLimitPaths := a.compileRateLimitPathsSpec(apiVersionDef.ExtendedPaths.RateLimit, RateLimit, conf)

Expand All @@ -1338,7 +1360,8 @@ func (a APIDefinitionLoader) getExtendedPathSpecs(apiVersionDef apidef.VersionIn
combinedPath = append(combinedPath, circuitBreakers...)
combinedPath = append(combinedPath, urlRewrites...)
combinedPath = append(combinedPath, requestSizes...)
combinedPath = append(combinedPath, goPlugins...)
combinedPath = append(combinedPath, goPlugins...)
combinedPath = append(combinedPath, lambdaPaths...)
combinedPath = append(combinedPath, persistGraphQL...)
combinedPath = append(combinedPath, virtualPaths...)
combinedPath = append(combinedPath, methodTransforms...)
Expand All @@ -1362,7 +1385,7 @@ func (a *APISpec) StopSessionManagerPool() {
}

func (a *APISpec) getURLStatus(stat URLStatus) RequestStatus {
switch stat {
switch stat {
case Ignored:
return StatusOkAndIgnore
case BlackList:
Expand Down Expand Up @@ -1407,12 +1430,14 @@ func (a *APISpec) getURLStatus(stat URLStatus) RequestStatus {
return StatusGoPlugin
case PersistGraphQL:
return StatusPersistGraphQL
case RateLimit:
return StatusRateLimit
default:
log.Error("URL Status was not one of Ignored, Blacklist or WhiteList! Blocking.")
return EndPointNotAllowed
}
case RateLimit:
return StatusRateLimit
case AWSLambda:
return StatusAWSLambda
default:
log.Error("URL Status was not one of Ignored, Blacklist or WhiteList! Blocking.")
return EndPointNotAllowed
}
}

// URLAllowedAndIgnored checks if a url is allowed and ignored.
Expand Down
1 change: 1 addition & 0 deletions gateway/api_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ func (gw *Gateway) processSpec(
// Earliest we can respond with cache get 200 ok
gw.mwAppendEnabled(&chainArray, newMockResponseMiddleware(baseMid.Copy()))
gw.mwAppendEnabled(&chainArray, &RedisCacheMiddleware{BaseMiddleware: baseMid.Copy(), store: &cacheStore})
gw.mwAppendEnabled(&chainArray, &AWSLambdaMiddleware{BaseMiddleware: baseMid.Copy()})
gw.mwAppendEnabled(&chainArray, &VirtualEndpoint{BaseMiddleware: baseMid.Copy()})
gw.mwAppendEnabled(&chainArray, &RequestSigning{BaseMiddleware: baseMid.Copy()})
gw.mwAppendEnabled(&chainArray, &GoPluginMiddleware{BaseMiddleware: baseMid.Copy()})
Expand Down
33 changes: 19 additions & 14 deletions gateway/model_urlspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ type URLSpec struct {
GoPluginMeta GoPluginMiddleware
PersistGraphQL apidef.PersistGraphQLMeta
RateLimit apidef.RateLimitMeta
AWSLambda apidef.AWSLambdaMeta

IgnoreCase bool
}

// modeSpecificSpec returns the respective field of URLSpec if it matches the given mode.
// Deprecated: Usage should not increase.
func (u *URLSpec) modeSpecificSpec(mode URLStatus) (interface{}, bool) {
switch mode {
switch mode {
case Ignored, BlackList, WhiteList:
return nil, true
case Cached:
Expand Down Expand Up @@ -83,16 +84,18 @@ func (u *URLSpec) modeSpecificSpec(mode URLStatus) (interface{}, bool) {
return &u.Internal, true
case GoPlugin:
return &u.GoPluginMeta, true
case PersistGraphQL:
return &u.PersistGraphQL, true
default:
return nil, false
}
case PersistGraphQL:
return &u.PersistGraphQL, true
case AWSLambda:
return &u.AWSLambda, true
default:
return nil, false
}
}

// matchesMethod checks if the given method matches the method required by the URLSpec for the current status.
func (u *URLSpec) matchesMethod(method string) bool {
switch u.Status {
switch u.Status {
case Ignored, BlackList, WhiteList:
return true
case Cached:
Expand Down Expand Up @@ -131,13 +134,15 @@ func (u *URLSpec) matchesMethod(method string) bool {
return method == u.Internal.Method
case GoPlugin:
return method == u.GoPluginMeta.Meta.Method
case PersistGraphQL:
return method == u.PersistGraphQL.Method
case RateLimit:
return method == u.RateLimit.Method
default:
return false
}
case PersistGraphQL:
return method == u.PersistGraphQL.Method
case RateLimit:
return method == u.RateLimit.Method
case AWSLambda:
return method == u.AWSLambda.Method
default:
return false
}
}

// matchesPath takes the input string and matches it against an internal regex.
Expand Down
Loading
Loading