aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.47k stars 1.16k forks source link

Bug: aws-sam-cli version 1.80 An invalid OpenApi version was detected #5035

Open shzxcv opened 1 year ago

shzxcv commented 1 year ago

Description:

openapi.yml

openapi: 3.0.3
info:
  title: test
  description: test
  version: 1.0.0

I can get the error that

$ sam local start-api
Error: An invalid OpenApi version was detected: '', must be one of 2.x or 3.x
make: *** [debug] Error 1

Steps to reproduce:

AWS SAM

Observed result:

Error: An invalid OpenApi version was detected: '', must be one of 2.x or 3.x

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: mac
  2. sam --version: SAM CLI, version 1.80.0
  3. AWS region: ap-northeast-1
{
  "version": "1.80.0",
  "system": {
    "python": "3.8.16",
    "os": "macOS-12.3.1-arm64-arm-64bit"
  },
  "additional_dependencies": {
    "docker_engine": "20.10.14",
    "aws_cdk": "Not available",
    "terraform": "Not available"
  }
}
lucashuy commented 1 year ago

Thanks for reporting this, can you post a sample template with resources that consume this OpenApi spec file? I am not able to reproduce this with the following examples:

template.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  HttpApiOpenApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      DefinitionUri: test.yaml

test.yaml:

openapi: "3.0.3"
info:
  title: HttpApiOpenApi
components:
  securitySchemes:
    Simple:
      type: apiKey
      in: header
      name: unused
      "x-amazon-apigateway-authorizer":
        authorizerPayloadFormatVersion: "2.0"
        enableSimpleResponses: true
        type: "request"
        identitySource: $request.header.header, $request.querystring.query
        authorizerUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerFunction.Arn}/invocations
paths:
  "/simple":
    get:
      security:
        - Simple: []
      x-amazon-apigateway-integration:
        payloadFormatVersion: "2.0"
        httpMethod: POST
        type: aws_proxy
        uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations
shzxcv commented 1 year ago

@lucashuy OK, I show you all the files.

Parameters: ENV: Type: String AllowedValues:

Resources: APIStack: Type: AWS::Serverless::Application Properties: Location: template/api.yml Parameters: ENV: !Ref ENV


- template/api.yml

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: test

Globals: Function: Timeout: 60

Parameters: ENV: Type: String

Resources: AuthAPI: Type: AWS::Serverless::Api Properties: Name: !Sub "auth-${ENV}-api" StageName: auth EndpointConfiguration: REGIONAL MethodSettings:

paths: /hello: get: summary: return hello description: hello world responses: '200': description: successfull content: application/json: schema: $ref: '#/components/schemas/Success' x-amazon-apigateway-integration: uri: Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthFunction.Arn}/invocations passthroughBehavior: when_no_templates httpMethod: GET type: aws_proxy

components: schemas: Success: description: successfull type: object Properties: message: type: string required:

lucashuy commented 1 year ago

At the moment, we do not current support nested stacks with local start-api (see #3306). Is it possible to extract the serverless API out and have that as a deployable stack as a possible workaround for now?

shzxcv commented 1 year ago

The 1.79.0 version works with this configuration. With 1.80.0, I get an issue error.

lucashuy commented 1 year ago

Hi, sorry about the incorrect assertion from before, it looks like the locations in the yaml files are relative where command is run, not where the file is located. Inside of template/api.yml, can you change the location to Location: template/openapi.yml for the Serverless Api resource?

shzxcv commented 1 year ago

@lucashuy I have made the changes exactly as they were made, but the error seems to be the same. Obviously the behavior seems to have changed between 1.79 and 1.80.

Location: template/openapi.yml

POlczak-ITTouch commented 1 year ago

We have the same issue in our project. The problem occurs with 1.80 and 1.84, but on 1.79 it runs ok.

lucashuy commented 1 year ago

Could you provide a reproducible example? In the OP, paths should be relative to the working directory, not the location of the file.

Debug output from the original reproducible example:

2023-05-31 15:51:13,794 | Successfully parsed location from AWS::Include transform: ./openapi.yml
2023-05-31 15:51:13,794 | Trying to download Swagger from ./openapi.yml
2023-05-31 15:51:13,794 | Unable to download Swagger file. File not found at location /Users/lucashuy/<folders>/5035/./openapi.yml
2023-05-31 15:51:13,794 | Found '0' APIs in resource 'AuthAPI'
2023-05-31 15:51:13,794 | Found '1' API Events in Serverless function with name 'AuthFunction'
2023-05-31 15:51:13,794 | Removed duplicates from '1' Explicit APIs and '0' Implicit APIs to produce '1' APIs
2023-05-31 15:51:13,794 | 1 APIs found in the template

This is still able to find an API since there is one implicitly defined under the Lambda Function, however if we take a look at the lines above that we can see that it's trying to find the file under the project root, not under template/.

After updating the path to Location: template/openapi.yml:

2023-05-31 16:01:23,518 | Detected Inline Swagger definition
2023-05-31 16:01:23,518 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:123456789012:function:AuthFunction/invocations
2023-05-31 16:01:23,519 | Extracted Function ARN: arn:aws:lambda:${AWS::Region}:123456789012:function:AuthFunction
2023-05-31 16:01:23,519 | Found '1' APIs in resource 'AuthAPI'
2023-05-31 16:01:23,519 | Found '1' API Events in Serverless function with name 'AuthFunction'
2023-05-31 16:01:23,519 | Removed duplicates from '2' Explicit APIs and '0' Implicit APIs to produce '1' APIs
2023-05-31 16:01:23,519 | 1 APIs found in the template

Here it is able to find the Swagger definition since the Location resolution is off the working directory. We can see this, as it found an endpoint for AuthAPI and we see that it removed the duplicate.

The reason why this is failing now (>=1.80.0), is that we explicitly check for an OpenApi version when parsing a body definition. Since it isn't able to resolve the file location, the document is not loaded.

alexandervantrijffel commented 6 months ago

I have the same issue with sam cli version 1.104.0 when running sam local start-api.

POlczak-ITTouch commented 6 months ago

Sorry, I wasn't able to provide a reproducible example, because our project is quite big and carving out a small-enough stub, which still would show this behavior on the newer versions would take a lot of work we couldn't afford at that time...

@alexandervantrijffel Would it be possible for you to provide a reproducible example?

alez007 commented 1 month ago

sorry for reigniting this one but using last version of sam as of this writing (1.119.0), the behaviour is as follows:

  1. if we use non relative path with openapi.yaml then the start-api works locally but the sam deploy fails with: Parameter Location of resource AWS::Include refers to a file or folder that does not exist /Users/user/projects/stuff-api/cloudformation/api/api/openapi.yaml because it needs relative path.
  2. using relative path doesn't work with start-api but works with sam deploy command