This project provides a Swagger Codegen 3.X template for generating Ambassador Mapping resources from OAS/Swagger definitions.
Clone this repo and build with
mvn clean install
and use with
java -cp <path to swagger-codegen-cli>:target/ambassador-swagger-codegen-1.0.0.jar \
io.swagger.codegen.v3.cli.SwaggerCodegen generate \
-l ambassadorGenerator \
-i <path/url to OAS definition> \
-o <output folder>
--additional-properties targetNamespace=mynamespace,targetService=myservice,servicePrefix=/myservice
The codegen template has several configuration options that can be provided either by command-line or via OAS extensions in your spec.
The command-line arguments are
targetService
: specifies the target service to use in the generated mapping file - requiredtargetNamespace
: specifies the target namespace to use in the generated mapping file, default is "ambassador"overrideExtensions
: boolean that controls if command-line arguments should override any extensions in the source OAS definition, default is falseservicePrefix
: specified an additional prefix to prepend all paths, for example "/myservice". This will be removed when forwarding to the target service (see example below)ignoreOperations
: a comma-separated list of operationIds to exclude from the generated mapping file
The corresponding OAS extensions are specified under an x-ambassador
node at either the top or operation level in your
OAS definition:
x-ambassador:
service: myservice
namespace: mynamespace
prefix: /myservice
If you want to exclude a specific operation via extensions you can simply add
x-ambassador:
ignore: true
to that operation.
Here comes a quick walkthrough showing howing this all works with Ambassador - using the Sample Petstore Service.
You'll need to have Ambassador running in a local cluster/namespace as created by the Ambassador Getting Started guide.
Start by deploying petstore to your local cluster using the provided petstore deployment file
kubectl apply -f petstore-deployment.yaml
Make sure petstore has been deployed alongside all the other Ambassador services;
> kubectl get pods -n ambassador
NAME READY STATUS RESTARTS AGE
ambassador-97dd6c4cb-v2vsx 1/1 Running 89 54d
ambassador-injector-7d7bdcf58b-phlsx 1/1 Running 1 54d
ambassador-redis-6594476754-wv569 1/1 Running 1 54d
petstore-6b6bf5f798-xqxf4 1/1 Running 0 13s
telepresence-proxy-7d4f567fb9-s8slz 1/1 Running 5 54d
Now run the provided maven generate profile to generate Ambassador mapping files from the public Petstore V3 OAS definition;
mvn test -P test
The mappings are all generated into the target/ambassador folder - apply the PetApi mapping using
kubectl apply -f target/ambassador/PetApi-mapping.yaml
Petstore is now mapped under /petstore using the Ambassador API Gateway - curl away!
> curl -k https://localhost/petstore/api/v3/pet/findByStatus?status=available
[{"id":1,"category":{"id":2,"name":"Cats"},"name":"Cat 1","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag1"},{"id":2,"name":"tag2"}],"status":"available"},{"id":2,"category":{"id":2,"name":"Cats"},"name":"Cat 2","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag2"},{"id":2,"name":"tag3"}],"status":"available"},{"id":4,"category":{"id":1,"name":"Dogs"},"name":"Dog 1","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag1"},{"id":2,"name":"tag2"}],"status":"available"},{"id":7,"category":{"id":4,"name":"Lions"},"name":"Lion 1","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag1"},{"id":2,"name":"tag2"}],"status":"available"},{"id":8,"category":{"id":4,"name":"Lions"},"name":"Lion 2","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag2"},{"id":2,"name":"tag3"}],"status":"available"},{"id":9,"category":{"id":4,"name":"Lions"},"name":"Lion 3","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag3"},{"id":2,"name":"tag4"}],"status":"available"},{"id":10,"category":{"id":3,"name":"Rabbits"},"name":"Rabbit 1","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag3"},{"id":2,"name":"tag4"}],"status":"available"}]
> curl -k https://localhost/petstore/api/v3/pet/2
{"id":2,"category":{"id":2,"name":"Cats"},"name":"Cat 2","photoUrls":["url1","url2"],"tags":[{"id":1,"name":"tag2"},{"id":2,"name":"tag3"}],"status":"available"}
(The "-k" option is added to allow the default self-signed certificate used by Ambassador)
The generated mapping is prohibitive in the sense that it only maps the exact matching method and path (including path parameters) for each operation. For example, the generated mapping for the getPetById operation above results in:
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: petstore-getpetbyid
namespace: ambassador
spec:
prefix: "/api/v3/pet/{.*}"
prefix_regex: true
method: GET
service: petstore
If a servicePrefix is specified this is removed from the url using a regex rewrite - for example if we add "servicePrefix=/petstore" to the configuration for the above generation we would get the following mapping:
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: petstore-getpetbyid
namespace: ambassador
spec:
prefix: "/petstore/api/v3/pet/{.*}"
prefix_regex: true
method: GET
service: petstore
regex_rewrite:
pattern: '/petstore(.*)'
substitution: '\1'
which effectively removes the prefix when forwarding the request to the service.
You can add the created target jar file to the standalone Swagger Generator as described at https://github.com/swagger-api/swagger-codegen/tree/3.0.0#swagger-generator--docker-image
An example invocation of the running generator with curl:
curl -X POST "<generator host>/api/generate" \
-H "accept: application/octet-stream" -H \
"Content-Type: application/json" -d \
"{\"lang\":\"ambassadorGenerator\",\"specURL\":\"https://petstore3.swagger.io/api/v3/openapi.json\",\
\"type\":\"CONFIG\",\"codegenVersion\":\"V3\",\"options\":{ \"additionalProperties\":{\"targetService\":\"petstore\"}}}"