Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: API Gateway Console Test button fails validation with @parser envelope ApiGatewayEnvelope because requestContext -> identity -> sourceIp value is not a valid IPv4 or IPv6 network #2526

Closed
Cihaan opened this issue May 15, 2024 · 5 comments · Fixed by #2531
Assignees
Labels
bug Something isn't working parser This item relates to the Parser Utility pending-release This item has been merged and will be released soon

Comments

@Cihaan
Copy link

Cihaan commented May 15, 2024

Expected Behavior

We should be able to generate a test form the API Gateway console that allows the ApiGatewayProxyEventModel to be validated and parsed by Zod.

Current Behavior

When generating a test from the API Gateway console, the value for the sourceIp in requestContext -> identity is "test-invoke-source-ip". Since this value is defined to be an ip here And so test events from the API Gateway console fail with a 502 error because of the resulting Zod ValidationError.

Code snippet

  RestApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Environment
      Name: !Sub '${ProjectName}-${Environment}-api'
      OpenApiVersion: '3.0.1' 
      TracingEnabled: true
      EndpointConfiguration: REGIONAL
      Auth: 
        DefaultAuthorizer: NONE
        AddDefaultAuthorizerToCorsPreflight: false
        ApiKeyRequired: false
      Cors:
        AllowMethods: "'DELETE,GET,HEAD,OPTIONS,POST,PUT'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
      MethodSettings:
        - HttpMethod: '*'
          ResourcePath: '/*'
          LoggingLevel: INFO
          DataTraceEnabled: true
          MetricsEnabled: true
          ThrottlingBurstLimit: 500
          ThrottlingRateLimit: 1000
      AccessLogSetting:
        DestinationArn: !GetAtt ApiAccessLogGroup.Arn
        Format: >-
          {
          "status": "$context.status",
          "traceId": "$context.xrayTraceId",
          "requestId": "$context.requestId",
          "requestTime": "$context.requestTime",
          "httpMethod": "$context.httpMethod",
          "responseLength": "$context.responseLength",
          "resourcePath": "$context.resourcePath",
          "resourceId": "$context.resourceId",
          "sourceIp": "$context.identity.sourceIp",
          "userAgent": "$context.identity.userAgent",
          "accountId": "$context.identity.accountId",
          "caller": "$context.identity.caller",
          "user": "$context.identity.user",
          "userArn": "$context.identity.userArn"
          }
      Tags:
        APPLI: !Ref ApplicationName
        ProjectName: !Ref ProjectName
        ENV: !Ref Environment
        Owner: !Ref Owner
// Lambda parses input and returns back the metadata field with a 200 status code
  UploadFileFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub '${ProjectName}-${Environment}-upload-file'
      CodeUri: ../../../dist/packages/backend/upload-file/
      CodeSigningConfigArn: !If [IsSandbox, !Ref AWS::NoValue, !Ref SignedCodeSigningConfigArn]
      Events:
        Api:
          Type: Api
          Properties:
            Path: /upload
            Method: POST
            RestApiId: !Ref RestApi
      Environment:
        Variables:
          BUCKET_NAME: !Ref S3Bucket
      Policies:
        - S3ReadPolicy:
            BucketName: !Ref S3Bucket
        - S3WritePolicy:
            BucketName: !Ref S3Bucket
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        EntryPoints:
          - index.js
// index.ts
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
import { parser } from '@aws-lambda-powertools/parser';
import { ApiGatewayEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { Tracer } from '@aws-lambda-powertools/tracer';
import Logger from '@fec-module/logger';
import { z } from 'zod';

import { uploadFileSchema } from 'packages/backend/src/upload-file/schema';

const tracer = new Tracer();

type UploadInput = z.infer<typeof uploadFileSchema>;

type UploadResponse = {
  cookies?: string[];
  isBase64Encoded?: true | false;
  statusCode: number;
  headers?: { [header: string]: string | number | boolean };
  body?: string;
};

class Lambda implements LambdaInterface {
  @Logger.injectLambdaContext({ logEvent: true })
  @tracer.captureLambdaHandler()
  @parser({ schema: uploadFileSchema, envelope: ApiGatewayEnvelope })
  public async handler(event: UploadInput): Promise<UploadResponse> {
    Logger.info('Received context', event);

    return {
      statusCode: 200,
      body: JSON.stringify({
        message: 'Request Received successfully with body',
        metadata: event.metadata,
      }),
    };
  }
}

// schema.ts
const uploadFileSchema = z.object({
  metadata: z.object({
    source_system: z.string(),
    category: z.string(),
    filename: z.string(),
    display_name: z.string().optional(),
    external_id: z.string().optional(),
    description: z.string().optional(),
    ttl: z.number().optional(),
    application_metadata: z.record(z.unknown()).optional(),
  }),
});

Steps to Reproduce

  • deploy the Api Gateway and the Lambda using SAM
  • go to the Test tab of the /upload route in the Api Gateway AWS Console
  • place following headers :
{
  "metadata": {
    "source_system": "source_system",
    "category": "category",
    "filename": "filename",
    "display_name": "display_name",
    "external_id": "external_id",
    "description": "descrition",
    "ttl": 1,
    "application_metadata": {
        "other": "other"
    }
  }
}
  • run test

following conversation in the Discord: https://discord.com/channels/1006478942305263677/1006527385409179678/1239877018653560872
(related to aws-powertools/powertools-lambda-python/issues/1562)

Possible Solution

update the Api Gateway zod schema to be:

z.union([z.string().ip(), z.literal('test-invoke-source-ip')]).optional()

Powertools for AWS Lambda (TypeScript) version

2.1.1-beta

AWS Lambda function runtime

20.x

Packaging format used

npm

Execution logs

No response

@Cihaan Cihaan added bug Something isn't working triage This item has not been triaged by a maintainer, please wait labels May 15, 2024
Copy link

boring-cyborg bot commented May 15, 2024

Thanks for opening your first issue here! We'll come back to you as soon as we can.
In the meantime, check out the #typescript channel on our Powertools for AWS Lambda Discord: Invite link

@dreamorosi dreamorosi self-assigned this May 15, 2024
@dreamorosi dreamorosi added confirmed The scope is clear, ready for implementation parser This item relates to the Parser Utility and removed triage This item has not been triaged by a maintainer, please wait labels May 15, 2024
@dreamorosi
Copy link
Contributor

Hi @Cihaan - thank you for reporting this and for opening the issue after our chat on Discord.

I'll be working on a PR to apply the workaround on the ip field as we discussed since I don't want to block you or others from testing.

Excluding major issues, the fix should land in the next release.

@dreamorosi
Copy link
Contributor

The PR is up and ready for review - as soon as another maintainer picks it up we'll likely be able to merge it.

Just to manage expectations, most of the team is attending events this and next week so I can't commit to a date for a release.

Thank you for your patience.

@Cihaan
Copy link
Author

Cihaan commented May 16, 2024

hey @dreamorosi, alright! thank you for taking the time

Copy link
Contributor

⚠️ COMMENT VISIBILITY WARNING ⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@github-actions github-actions bot added pending-release This item has been merged and will be released soon and removed confirmed The scope is clear, ready for implementation labels May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working parser This item relates to the Parser Utility pending-release This item has been merged and will be released soon
Projects
Status: Coming soon
Development

Successfully merging a pull request may close this issue.

2 participants