Gloo Edge does not populate the identity object with the relevant data when wrapAsApiGateway is enabled
sadieleob opened this issue · comments
Gloo Edge Product
Enterprise
Gloo Edge Version
1.16.8
Kubernetes Version
v1.27.13-eks-3af4770
Describe the bug
When setting GE to mimic the AWS API GW behavior by setting to true unwrapAsApiGateway and wrapAsApiGateway, it looks like GE might not be wrapping the request in a way that Lambda function expects.
AWS Lambda logs:
java.lang.NullPointerException: Cannot invoke "com.amazonaws.serverless.proxy.model.ApiGatewayRequestIdentity.getAccessKey()" because the return value of "com.amazonaws.serverless.proxy.model.AwsProxyRequestContext.getIdentity()" is null
Expected Behavior
GE wraps the request to AWS Lambda in a manner identical to how API Gateway does, including fields such as the identity in the event object.
Steps to reproduce the bug
- Create AWS lambda:
mvn archetype:generate -DgroupId=my.service -DartifactId=my-service -Dversion=1.0-SNAPSHOT \
-DarchetypeGroupId=com.amazonaws.serverless.archetypes \
-DarchetypeArtifactId=aws-serverless-jersey-archetype \
-DarchetypeVersion=2.0.1
Run "mvn clean package" to generate a zip file.
Deploy the zip file in a Lambda function. Select Lambda Java version for the Lambda runtime same as what you have in pom.xml.
AWS Lambda
- Runtime: Java 21,
- Handler: my.service.StreamLambdaHandler::handleRequest,
- Arch: x86_64
Testing
Use following test event:
{
"resource": "/ping",
"path": "/ping",
"httpMethod": "GET",
"requestContext": {
"stage": "stage1",
"identity": {
"apikey": "XXXXXXXXXXXXX",
"userAgent": "curl/7.79.1"
},
"resourcePath": "/",
"httpMethod": "GET",
"path": "/"
},
"headers": {
"Host": "www.example.com"
},
"multiValueHeaders": {
"Host": ["www.example.com"]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"body": null,
"isBase64Encoded": false
}
- Define the following VS and US:
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: hello-lambda
namespace: suresh
spec:
aws:
destinationOverrides:
requestTransformation: false
unwrapAsApiGateway: true
wrapAsApiGateway: true
lambdaFunctions:
- logicalName: sadiel-mvn
qualifier: $LATEST
region: us-west-2
secretRef:
name: aws-creds
namespace: gloo-system
connectionConfig:
maxRequestsPerConnection: 1
---
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: cbp-portal
namespace: default
spec:
virtualHost:
domains:
- soloist.servebeer.com
routes:
- matchers:
- prefix: /
routeAction:
single:
destinationSpec:
aws:
logicalName: sadiel-mvn
upstream:
name: hello-lambda
namespace: suresh
- GE Settings
gloo:
awsOptions:
fallbackToFirstFunction: true
- Requests:
curl -v -H"Host: soloist.servebeer.com" http://soloist.servebeer.com/v1/ping
curl -v -H"Host: soloist.servebeer.com" http://soloist.servebeer.com/v1/ping -H "api-key: $API_KEY" -H "Content-Type: application/json" -d '{"resource": "/ping","path": "/ping","httpMethod": "GET","requestContext": {"stage": "stage1","identity": {"apikey": "xxxxxxxxxx","userAgent": "curl/7.79.1"},"resourcePath": "/","httpMethod": "GET","path": "/"},"headers": {"Host": "www.example.com"},"multiValueHeaders": {"Host": ["www.example.com"]},"queryStringParameters": null,"multiValueQueryStringParameters": null,"pathParameters": null,"stageVariables": null,"body": null,"isBase64Encoded": false}'
- Response:
{
"upstream_host": ""18.246.196.137:443"",
"method": ""POST",
"protocol": "HTTP/1.1"",
"path": "/2015-03-31/functions/sadiel-mvn/invocations?Qualifier=%24LATEST",
"duration": 19,
"response_code": 502,
"upstreamCluster": "hello-lambda_suresh",
"x-forwarded-for": ""-"",
"response_flag": "-",
"starttime": "[2024-05-29T17:28:57.019Z]",
"request-id": ""2699f1e0-6f5f-4947-9c70-65e7c6b48b8b"",
"requestHeaders": null,
"upstreamHost": "18.246.196.137:443",
"upstream_svc_time": null
}
Additional Environment Detail
No response
Additional Context
No response
┆Issue is synchronized with this Asana task by Unito
Zendesk ticket #3749 has been linked to this issue.
tested in 1.16.10 and the issue persists.
helm list -n gloo-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
gloo gloo-system 17 2024-06-17 09:54:43.728908 -0500 CDT deployed gloo-ee-1.16.10
curl -v -H"Host: soloist.servebeer.com" http://soloist.servebeer.com/v1/ping -H "api-key: $API_KEY" -H "Content-Type: application/json" -d '{"resource": "/ping","path": "/ping","httpMethod": "GET","requestContext": {"stage": "stage1","identity": {"apikey": "xxxxxxxxxxxxx","userAgent": "curl/7.79.1"},"resourcePath": "/","httpMethod": "GET","path": "/"},"headers": {"Host": "www.example.com"},"multiValueHeaders": {"Host": ["www.example.com"]},"queryStringParameters": null,"multiValueQueryStringParameters": null,"pathParameters": null,"stageVariables": null,"body": null,"isBase64Encoded": false}'
* Host soloist.servebeer.com:80 was resolved.
* IPv6: (none)
* IPv4: 35.167.216.82
* Trying 35.167.216.82:80...
* Connected to soloist.servebeer.com (35.167.216.82) port 80
> POST /v1/ping HTTP/1.1
> Host: soloist.servebeer.com
> User-Agent: curl/8.6.0
> Accept: */*
> api-key: xxxxxxxxxx
> Content-Type: application/json
> Content-Length: 485
>
< HTTP/1.1 502 Bad Gateway
< content-type: application/json
< content-length: 29
< x-ratelimit-limit: 1000
< x-ratelimit-remaining: 999
< x-ratelimit-reset: 1
< date: Mon, 17 Jun 2024 15:06:28 GMT
< server: envoy
<
* Connection #0 to host soloist.servebeer.com left intact
{"message": "Gateway Timeout"}%
2024-06-17T14:51:45.840Z
java.lang.NullPointerException: Cannot invoke "com.amazonaws.serverless.proxy.model.ApiGatewayRequestIdentity.getAccessKey()" because the return value of "com.amazonaws.serverless.proxy.model.AwsProxyRequestContext.getIdentity()" is null
We need to make sure that we compare the full requests that are being sent by Gloo Edge with the full requests that are being sent by the AWS API Gateway to verify that there are no other fields and objects not being populated.
@nfuden to look at this issue for scope/estimation.