Интеграция шлюза Terraform API с Swagger (Localstack) - PullRequest
0 голосов
/ 13 января 2020

Я создал простую лямбду API Crud, используя mongoDb и nodeJs, и она работает нормально. поэтому я перешел к другому шагу: в настоящее время я создаю AWS API-шлюз с terraform, используя открытое API c из файла yaml. это мой файл чванства:

info:
  description: "API Ankan-v2"
  version: "V0.0.1"
  title: "ANKAN V2 API"
host: "localhost:4567"
basePath: "/restapis/api/{apiId}/test/_user_request_"
tags:
  - name: "user"
    description: "Operations about user"
schemes:
  - "http"
#    - "https"
paths:
  /documents/{documentId}:
    get:
      tags:
        - "document"
      summary: "Find document by ID"
      description: "Returns a single document"
      operationId: "readOneDocument"
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses:
        200:
          description: "successful operation"
          schema:
            $ref: "#/definitions/Document"
        404:
          description: "document not found"
      x-amazon-apigateway-integration:
        uri: ${get_lambda_arn}
        passthroughBehavior: "WHEN_NO_MATCH"
        httpMethod: "POST"
        type: "AWS_PROXY"
    options:
      consumes:
        - "application/json"
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses:
        200:
          description: "200 response"
          schema:
            $ref: "#/definitions/Document"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "when_no_match"
        type: "mock"
    x-amazon-apigateway-any-method:
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
        uri: ${get_lambda_arn}
        passthroughBehavior: "WHEN_NO_MATCH"
        httpMethod: "POST"
        cacheNamespace: "1rnijn"
        cacheKeyParameters:
          - "method.request.path.documentId"
        type: "AWS"
definitions:
  Document:
    type: "object"
    required:
      - "documentName"
      - "documentPath"
      - "miniature"
      - "status"
      - "date"
    properties:
      _id:
        type: "string"
        readOnly: true
      documentName:
        type: "string"
      documentPath:
        type: "string"
      miniature:
        type: "string"
      status:
        type: "string"
        enum:
          - "VALID"
          - "ERROR"
          - "ONLOAD"
      date:
        type: "string"
        format: "date"
    xml:
      name: "Document" 

в моей терраформе я удалил интеграцию и метод, потому что добавил их в свой чванство. поэтому мне нужно импортировать файл swagger в aws_api_gateway_rest_api с body = data.template_file.swagger.rendered

resource "aws_api_gateway_rest_api" "api" {
  name = "api-gateway"
  description = "document api"
  body = data.template_file.swagger.rendered

}


data "template_file" "swagger" {
  template = jsonencode("${path.module}/../../../../shared/swagger.yaml")

  vars = {
    get_lambda_arn = local.get_lambda_arn
  }
}
output "json" {
  value = data.template_file.swagger.rendered
}

locals {
  get_lambda_arn = aws_lambda_function.lambda_document.invoke_arn
}

resource "aws_api_gateway_resource" "documents" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  parent_id   = aws_api_gateway_rest_api.api.root_resource_id
  path_part   = "documents"
  depends_on  = [aws_api_gateway_rest_api.api]
}

resource "aws_api_gateway_resource" "document_by_id" {
  parent_id   = aws_api_gateway_resource.documents.id
  path_part   = "{documentId}"
  rest_api_id = aws_api_gateway_rest_api.api.id
}


resource "aws_api_gateway_deployment" "ApiDeloyment" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  stage_name = "INT"

  depends_on = [aws_api_gateway_rest_api.api]
}


resource "aws_lambda_function" "lambda_document" {
  function_name = "lambda_document"
  handler = "lambda.handler"
  role = "arn:aws::iam::123456:role/irrelevant"
  runtime = "nodejs10.x"
  filename = "${path.module}/lambda.zip"

  source_code_hash = filebase64sha256("${path.module}/lambda.zip")
}

После применения terraform я получил это сообщение в журналах terraform

terraform apply --auto-approve
module.backend_api.module.document.aws_api_gateway_rest_api.api: Creating...
module.backend_api.module.document.aws_lambda_function.lambda_document: Creating...
module.backend_api.module.document.aws_lambda_function.lambda_document: Creation complete after 5s [id=lambda_document]
module.backend_api.module.document.data.template_file.swagger: Refreshing state...
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [10s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [20s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [30s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [40s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [50s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [1m0s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [1m10s elapsed]

и мои docker -композитные журналы покажите это

localstack        | 2020-01-13T07:37:56:ERROR:localstack.services.generic_proxy: Error forwarding request: Expecting value: line 1 column 1 (char 0) Traceback (most recent call last):
localstack        |   File "/opt/code/localstack/localstack/services/generic_proxy.py", line 242, in forward
localstack        |     path=path, data=data, headers=forward_headers)
localstack        |   File "/opt/code/localstack/localstack/services/apigateway/apigateway_listener.py", line 53, in forward_request
localstack        |     data = data and json.loads(to_str(data))
localstack        |   File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
localstack        |     return _default_decoder.decode(s)
localstack        |   File "/usr/lib/python3.7/json/decoder.py", line 337, in decode
localstack        |     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
localstack        |   File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode
localstack        |     raise JSONDecodeError("Expecting value", s, err.value) from None
localstack        | json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

PS: я пытался с JSON, но та же проблема

есть ли решение для этого? я хочу интегрировать Swagger с API-шлюзом, используя terraform в localstack

1 Ответ

0 голосов
/ 05 мая 2020

Это проблема с библиотекой мото. Под капотом локальный стек использует moto для создания своих ресурсов, включая mock api gateway. К сожалению, moto в настоящее время не поддерживает параметр body для размещения определения файла swagger как части развертывания шлюза API. Таким образом, даже если вы предоставите действительный файл swagger и конфигурацию шлюза API (ie, которая работает в aws), localstack не сможет его построить.

...