Skip to content

Commit 0ab2ded

Browse files
Added Developer Portal support (#4)
* OpenAPI integration work in progress * API Gateway updates * API Gateway support - beta release * README updated * README updated * README updated * README updated * README updated * README updated * Declaration schema updated, Developer portal alpha release * Postman collection updated * Devportal alpha release commit * Devportal alpha release commit * Added Developer Portal support
1 parent c5da460 commit 0ab2ded

21 files changed

+338
-102
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/.idea/
22
/src/__pycache__/
3+
/src/Contrib/__pycache__/
4+
/contrib/devportal/src/__pycache__/
35
/venv/

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM alpine:latest
2+
3+
RUN apk update && apk upgrade && \
4+
apk add --update --no-cache python3
5+
6+
WORKDIR /deployment
7+
8+
COPY etc/ etc/
9+
COPY src/ src/
10+
COPY templates/ templates/
11+
12+
RUN python3 -m venv /deployment/env/ && \
13+
source /deployment/env/bin/activate && \
14+
# python3 -m pip install --upgrade pip && \
15+
pip3 install --no-cache --upgrade pip setuptools virtualenv && \
16+
pip3 install -r src/requirements.txt
17+
18+
WORKDIR /deployment/src
19+
CMD ["/deployment/env/bin/python3", "./main.py"]

README.md

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
# NGINX-Declarative-API
22

3-
This tool provides a set of declarative REST API for NGINX Instance Manager.
3+
This project provides a set of declarative REST API for [NGINX Instance Manager](https://docs.nginx.com/nginx-management-suite/nim/).
44

55
It can be used to manage NGINX Plus configuration lifecycle and to create NGINX Plus configurations using JSON service definitions.
66

7-
GitOps integration is supported when used with NGINX Instance Manager: source of truth is checked for updates (NGINX App Protect policies, TLS certificates, keys and chains/bundles) and NGINX configurations are automatically kept in sync.
7+
GitOps integration is supported when used with NGINX Instance Manager: source of truth is checked for updates (NGINX App Protect policies, TLS certificates, keys and chains/bundles, Swagger/OpenAPI definitions) and NGINX configurations are automatically kept in sync.
88

99
Use cases include:
1010

1111
- Rapid configuration generation and templating
1212
- CI/CD integration with NGINX Instance Manager (instance groups and staged configs)
1313
- NGINX App Protect DevSecOps integration
1414
- API Gateway deployments with automated Swagger / OpenAPI schemas import
15+
- API Developer portals zero-touch deployment
1516
- GitOps integration with source of truth support for
1617
- NGINX App Protect WAF policies
1718
- TLS certificates, keys and chains/bundles
@@ -22,7 +23,7 @@ Use cases include:
2223

2324
## Requirements
2425

25-
- NGINX Instance Manager 2.10+
26+
- NGINX Instance Manager 2.14+
2627
- NGINX Plus R30 or newer
2728

2829
## Architecture
@@ -88,8 +89,9 @@ NGINX Instance Manager ->> NGINX: Publish config to NGINX instances
8889
| Cookie-based stickiness | X | |
8990
| Maps | X | |
9091
| NGINX Plus REST API access | X | |
91-
| NGINX App Protect WAF | Per-policy CRUD at `server` and `location` level with dataplane-based bundle compilation | Security policies can be dynamically fetched from source of truth |
92-
| API Gateway | Swagger and OpenAPI YAML and JSON schema support | Automated configuration, HTTP methods and rate limiting enforcement |
92+
| NGINX App Protect WAF | Per-policy CRUD at `server` and `location` level with dataplane-based bundle compilation | Security policies can be dynamically fetched from source of truth |
93+
| API Gateway | Swagger and OpenAPI YAML and JSON schema support | Automated configuration, HTTP methods and rate limiting enforcement |
94+
| API Developer Portal | Swagger and OpenAPI YAML and JSON schema support | Based on Redocly |
9395

9496
## How to use
9597

@@ -99,42 +101,26 @@ Usage details and JSON schema are available here:
99101

100102
A sample Postman collection and usage instructions can be found [here](/contrib/postman)
101103

102-
### Using docker-compose
104+
## How to run
103105

104-
This is the recommended method to run NGINX Declarative API on a Linux virtual machine. Refer to [installation instructions](https://github.com/fabriziofiorucci/NGINX-Declarative-API/tree/main/contrib/docker-compose)
106+
Docker-compose is the recommended method to run NGINX Declarative API on a Linux virtual machine. Full details are available [here](https://github.com/fabriziofiorucci/NGINX-Declarative-API/tree/main/contrib/docker-compose)
105107

106-
### As a Python application
108+
## Building Docker images
107109

108-
This repository has been tested with and requires Python 3.9 or newer.
109-
A running instance of [redis](https://redis.io/) is required: redis host and port can be configured in the `config.toml` file.
110+
Docker images can be built and run using:
110111

111-
Run NGINX Declarative API using:
112+
git clone https://github.com/fabriziofiorucci/NGINX-Declarative-API
112113

113-
```
114-
$ git clone https://github.com/fabriziofiorucci/NGINX-Declarative-API
115-
$ cd NGINX-Declarative-API/src
116-
$ pip install -r requirements.txt
117-
$ python3 main.py
118-
```
119-
120-
### As a Docker image
121-
122-
The docker image can be built and run using:
123-
124-
```
125-
$ git clone https://github.com/fabriziofiorucci/NGINX-Declarative-API
126-
$ cd NGINX-Declarative-API
127-
$ docker build -t nginx-declarative-api:latest -f contrib/docker/Dockerfile .
128-
$ docker run --name nginx-declarative-api -d -p 5000:5000 nginx-declarative-api:latest
129-
```
130-
131-
Pre-built docker images are available on Docker Hub at https://hub.docker.com/repository/docker/fiorucci/nginx-declarative-api/general and can be run using:
114+
cd NGINX-Declarative-API
115+
docker build --no-cache -t fiorucci/nginx-declarative-api -f ./Dockerfile .
116+
docker run --name nginx-declarative-api -d -p 5000:5000 fiorucci/nginx-declarative-api
132117

133-
```
134-
$ docker run --rm --name nginx-declarative-api -d -p 5000:5000 <IMAGE_NAME>
135-
```
118+
cd contrib/devportal
119+
docker build --no-cache -t fiorucci/nginx-declarative-api-devportal .
120+
docker run --name devportal -d -p 5001:5000 fiorucci/nginx-declarative-api-devportal
136121

137-
Pre-built images are configured to access the redis instance on host:port `127.0.0.1:6379`. This can be changed by mounting a custom `config.toml` file on the `nginx-declarative-api` container.
122+
Pre-built docker images are available on Docker Hub at https://hub.docker.com/repository/docker/fiorucci/nginx-declarative-api/general
123+
Configuration can be customized mounting `config.toml` as a volume `nginx-declarative-api` docker image as a volume to customize
138124

139125
## REST API documentation
140126

USAGE-v3.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,16 @@ Locations `.declaration.http.servers[].locations[].uri` match modifiers in `.dec
5353

5454
### API Gateway ###
5555

56-
Swagger files and OpenAPI schemas can be used to automatically configure NGINX as an API Gateway.
56+
Swagger files and OpenAPI schemas can be used to automatically configure NGINX as an API Gateway. Developer portal creation is supported through [Redocly](https://redocly.com/)
5757

5858
Declaration path `.declaration.http.servers[].locations[].apigateway` defines the API Gateway configuration:
5959

6060
- `openapi_schema` - the base64-encoded schema, or the schema URL. YAML and JSON are supported
61-
- `strip_uri` - removes the `.declaration.http.servers[].locations[].uri` part of the URI before forwarding requests to the upstream
62-
- `server_url` - the base URL of the upstream server
61+
- `api_gateway.enabled` - enable/disable API Gateway provisioning
62+
- `api_gateway.strip_uri` - removes the `.declaration.http.servers[].locations[].uri` part of the URI before forwarding requests to the upstream
63+
- `api_gateway.server_url` - the base URL of the upstream server
64+
- `developer_portal.enabled` - enable/disable Developer portal provisioning
65+
- `developer_portal.uri` - the trailing part of the Developer portal URI, this is appended to `.declaration.http.servers[].locations[].uri`. If omitted it defaults to `devportal.html`
6366
- `rate_limit` - optional, used to enforce rate limiting at the API Gateway level
6467

6568
A sample API Gateway declaration to publish the `https://petstore.swagger.io` REST API and enforce:
@@ -108,8 +111,15 @@ is:
108111
"urimatch": "prefix",
109112
"apigateway": {
110113
"openapi_schema": "https://petstore.swagger.io/v2/swagger.json",
111-
"strip_uri": true,
112-
"server_url": "https://petstore.swagger.io/v2",
114+
"api_gateway": {
115+
"enabled": true,
116+
"strip_uri": true,
117+
"server_url": "https://petstore.swagger.io/v2"
118+
},
119+
"developer_portal": {
120+
"enabled": true,
121+
"uri": "/petstore-devportal.html"
122+
},
113123
"rate_limit": {
114124
"profile": "petstore_ratelimit",
115125
"httpcode": 429,
@@ -142,6 +152,10 @@ It can be tested using:
142152

143153
curl -iH "Host: apigw.nginx.lab" http://<NGINX_INSTANCE_IP_ADDRESS>/petstore/store/inventory
144154

155+
The API Developer portal can be accessed at:
156+
157+
http://<NGINX_INSTANCE_IP_ADDRESS>/petstore/petstore-devportal.html
158+
145159
### Maps ###
146160

147161
Map entries `.declaration.maps[].entries.keymatch` can be:

contrib/devportal/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM redocly/cli
2+
3+
WORKDIR /deployment
4+
5+
COPY src/ src/
6+
7+
RUN apk update && \
8+
apk add --update --no-cache bash python3 && \
9+
python3 -m ensurepip && \
10+
pip3 install --no-cache --upgrade pip setuptools virtualenv && \
11+
virtualenv /deployment/env/ && source /deployment/env/bin/activate && \
12+
python3 -m pip install --upgrade pip && \
13+
pip3 install -r /deployment/src/requirements.txt
14+
15+
ENTRYPOINT [ "/deployment/src/start.sh" ]

contrib/devportal/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Developer portal add-on
2+
3+
This is a wrapper for [Redocly CLI](https://redocly.com/docs/cli/) used by the NGINX declarative API to create and publish developer portals
4+
5+
To build:
6+
7+
docker build --no-cache -t <YOUR_TARGET_IMAGE_NAME> .
8+
9+
To run the pre-build image:
10+
11+
docker run --rm -d -p 5001:5000 --name devportal fiorucci/nginx-declarative-api-devportal
12+
13+
To test:
14+
15+
curl -i -w '\n' 127.0.0.1:5001/v1/devportal -X POST -H "Content-Type: application/json" -d @<OPENAPI_JSON_SCHEMA_FILENAME>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
typing
2+
uvicorn
3+
fastapi
4+
uuid

contrib/devportal/src/server.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import pathlib
2+
import uvicorn
3+
import subprocess
4+
import json
5+
import uuid
6+
7+
from typing import Any, Dict, AnyStr, List, Union
8+
9+
from fastapi import FastAPI, Request
10+
from fastapi.responses import PlainTextResponse, Response, JSONResponse
11+
12+
app = FastAPI(
13+
title="Redoc connector",
14+
version="1.0.0",
15+
contact={"name": "GitHub", "url": "https://github.com/fabriziofiorucci/NGINX-Declarative-API"}
16+
)
17+
18+
JSONObject = Dict[AnyStr, Any]
19+
JSONArray = List[Any]
20+
JSONStructure = Union[JSONArray, JSONObject]
21+
22+
@app.post("/v1/devportal", status_code=200, response_class=JSONResponse)
23+
def post_devportal(response: Response, request: JSONStructure = None):
24+
if request:
25+
try:
26+
sessionUUID = uuid.uuid4()
27+
apiSchema = json.dumps(request)
28+
tmpFileBase = f"/tmp/{sessionUUID}"
29+
tmpFileSchema = f"{tmpFileBase}.json"
30+
tmpFileDocs = f"{tmpFileBase}.html"
31+
tmpFile = open(tmpFileSchema,"w")
32+
tmpFile.write(apiSchema)
33+
tmpFile.close()
34+
35+
output = subprocess.check_output(f"redocly build-docs '{tmpFileSchema}' --output={tmpFileDocs}", shell=True)
36+
37+
with open(tmpFileDocs, 'r') as file:
38+
devPortal = file.read().replace('\n','')
39+
40+
return JSONResponse (content={'status': 'success','apischema': f'{apiSchema}','devportal': f'{devPortal}'}, status_code=200)
41+
except subprocess.CalledProcessError as e:
42+
return JSONResponse (content={'status': str(e)}, status_code=400)
43+
finally:
44+
schemaFile = pathlib.Path(tmpFileSchema)
45+
if schemaFile.is_file():
46+
schemaFile.unlink()
47+
48+
docsFile = pathlib.Path(tmpFileDocs)
49+
if docsFile.is_file():
50+
docsFile.unlink()
51+
else:
52+
return JSONResponse (content={'status': 'invalid body'}, status_code=400)
53+
54+
if __name__ == '__main__':
55+
uvicorn.run("server:app", host='0.0.0.0', port=5000)

contrib/devportal/src/start.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
# https://redocly.com/docs/cli/commands/build-docs/
4+
5+
# Disable telemetry collection
6+
# https://github.com/Redocly/redocly-cli/#data-collection
7+
export REDOCLY_TELEMETRY=off
8+
9+
/deployment/env/bin/python /deployment/src/server.py

contrib/docker-compose/README.md

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Docker compose
22

3-
NGINX Declarative API can be deployed using docker compose on a Linux virtual machine running Docker.
3+
NGINX Declarative API can be deployed using docker compose on a Linux virtual machine running docker-compose v2.20+
44

55
Usage:
66

@@ -18,13 +18,14 @@ NGINX Declarative API - https://github.com/fabriziofiorucci/NGINX-Declarative-AP
1818
1919
=== Options:
2020
21-
-h - This help
22-
-c [start|stop] - Deployment command
21+
-h - This help
22+
-c [start|stop|restart] - Deployment command
2323
2424
=== Examples:
2525
26-
Deploy NGINX DAPI: ./nginx-dapi.sh -c start
27-
Remove NGINX DAPI: ./nginx-dapi.sh -c stop
26+
Deploy NGINX DAPI : ./nginx-dapi.sh -c start
27+
Remove NGINX DAPI : ./nginx-dapi.sh -c stop
28+
Restart NGINX DAPI: ./nginx-dapi.sh -c restart
2829
```
2930

3031
## How to deploy
@@ -34,26 +35,59 @@ NGINX Declarative API - https://github.com/fabriziofiorucci/NGINX-Declarative-AP
3435
- [API v1](/USAGE-v1.md) - deprecated
3536
- [API v2](/USAGE-v2.md)
3637

37-
## Starting & stopping with docker-compose
38+
## How to run
3839

3940
Starting NGINX Declarative API:
4041

4142
```
4243
$ ./nginx-dapi.sh -c start
44+
-> Updating docker images
45+
[+] Pulling 3/3
46+
✔ nginx-dapi Pulled
47+
✔ redis Pulled
48+
✔ devportal Pulled
4349
-> Deploying NGINX Declarative API
44-
Creating network "nginx-dapi_default" with the default driver
45-
Creating redis ... done
46-
Creating nginx-dapi ... done
47-
$
50+
[+] Running 3/3
51+
✔ Container redis Running
52+
✔ Container devportal Running
53+
✔ Container nginx-dapi Started
4854
```
4955

5056
Stopping NGINX Declarative API:
5157

5258
```
5359
$ ./nginx-dapi.sh -c stop
5460
-> Undeploying NGINX Declarative API
55-
Removing redis ... done
56-
Removing nginx-dapi ... done
57-
Removing network nginx-dapi_default
58-
$
61+
[+] Running 4/4
62+
✔ Container nginx-dapi Removed
63+
✔ Container devportal Removed
64+
✔ Container redis Removed
65+
✔ Network nginx-dapi_default Removed
5966
```
67+
68+
Restarting NGINX Declarative API:
69+
70+
```
71+
$ ./nginx-dapi.sh -c restart
72+
[+] Running 4/4
73+
✔ Container devportal Removed
74+
✔ Container nginx-dapi Removed
75+
✔ Container redis Removed
76+
✔ Network nginx-dapi_default Removed
77+
-> Updating docker images
78+
[+] Pulling 3/3
79+
✔ nginx-dapi Pulled
80+
✔ redis Pulled
81+
✔ devportal Pulled
82+
-> Deploying NGINX Declarative API
83+
[+] Running 4/4
84+
✔ Network nginx-dapi_default Created-> Undeploying NGINX Declarative API
85+
[+] Running 4/4
86+
✔ Container nginx-dapi Removed
87+
✔ Container devportal Removed
88+
✔ Container redis Removed
89+
✔ Network nginx-dapi_default Removed
90+
✔ Container devportal Started
91+
✔ Container redis Started
92+
✔ Container nginx-dapi Started
93+
```

0 commit comments

Comments
 (0)