Skip to content

Commit e52d09e

Browse files
committed
feat: Add NGINX API gateway demo (#8)
1 parent ce319b4 commit e52d09e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1362
-12
lines changed

Diff for: .gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
*~
77
\#*
88

9+
#######################
10+
# Terraform variables #
11+
#######################
12+
*.tfvars
13+
914
##########################
1015
# Backup/temporary files #
1116
##########################

Diff for: NginxOneConsole-demo/readme.md

-5
This file was deleted.

Diff for: README.md

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
1-
# nginx_demos
1+
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
2+
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/nginx/nginx-demos/badge)](https://securityscorecards.dev/viewer/?uri=github.com/nginx/nginx-demos)
3+
[![Community Support](https://badgen.net/badge/support/community/cyan?icon=awesome)](/SUPPORT.md)
4+
[![Community Forum](https://img.shields.io/badge/community-forum-009639?logo=discourse&link=https%3A%2F%2Ffanyv88.com%3A443%2Fhttps%2Fcommunity.nginx.org)](https://community.nginx.org)
5+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6+
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](/CODE_OF_CONDUCT.md)
27

3-
## Requirements
8+
# NGINX Demos
49

5-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam elit turpis, varius et arcu elementum, viverra rhoncus sem. Aliquam nec sodales magna, et egestas enim. Mauris lobortis ultrices euismod. Pellentesque in arcu lacus. Mauris cursus laoreet nulla, ac vehicula est. Vestibulum eu mauris quis lorem consectetur aliquam ac nec quam. Vestibulum commodo pharetra mi, at bibendum neque faucibus ut. Mauris et tortor sed sem consectetur eleifend ut non magna. Praesent feugiat placerat nibh, varius viverra orci bibendum sed. Vestibulum dapibus ex ut pulvinar facilisis. Quisque sodales enim et augue tempor mattis. Suspendisse finibus congue felis, ac blandit ligula. Praesent condimentum ultrices odio quis semper. Nunc ultrices, nibh quis mattis pellentesque, elit nulla bibendum felis, quis dapibus erat turpis ac urna.
10+
This repository contains a collection of curated and updated NGINX demos covering NGINX offerings.
611

7-
## Getting Started
12+
## Repository Structure
813

9-
Duis sit amet sapien vel velit ornare vulputate. Nulla rutrum euismod risus ac efficitur. Curabitur in sagittis elit, a semper leo. Suspendisse malesuada aliquam velit, eu suscipit lorem vehicula at. Proin turpis lacus, semper in placerat in, accumsan non ipsum. Cras euismod, elit eget pretium laoreet, tortor nulla finibus tortor, nec hendrerit elit turpis ut eros. Quisque congue nisi id mauris molestie, eu condimentum dolor rutrum. Nullam eleifend elit ac lobortis tristique. Pellentesque nec tellus non mauris aliquet commodo a eu elit. Ut at feugiat metus, at tristique mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;
14+
The demos are divided by NGINX product offering into unique distinct folders. Each folder then contains one or more demos covering various use cases within the respective product offering.
1015

11-
## How to Use
16+
Each demo might have unique deployment requirements. Please refer to each individual README for more details.
1217

13-
Maecenas at vehicula justo. Suspendisse posuere elementum elit vel posuere. Etiam quis pulvinar massa. Integer tempor semper risus, vitae maximus eros ullamcorper vitae. In egestas, ex vitae gravida sodales, ipsum dolor varius est, et cursus lorem dui a mi. Morbi faucibus ut nisi id faucibus. Sed quis ullamcorper ex. In et dolor id nunc interdum suscipit.
18+
## Available Demos
19+
20+
|Title|Description|
21+
|-----|-----------|
22+
|NGINX API gateway|Configure NGINX as an API gateway|
23+
|NGINX Gateway Fabric|Simple overview of configuring NGINX Gateway Fabric to route traffic within Kubernetes|
24+
|NGINX Ingress Controller|Simple overview of deploying and configuring NGINX Ingress Controller|
25+
|NGINX One|Simple overview of NGINX One and its capabilities|
1426

1527
## Contributing
1628

Diff for: nginx-gateway-fabric/appworld/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NGINX Gateway Fabric Demo
2+
3+
This demo contains the files used in the NGINX Gateway Fabric AppWorld demo.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

Diff for: nginx-one/appworld/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NGINX One Console Demo
2+
3+
The material for this demo can be found within the NGINX One Workshop GitHub repository at <https://github.com/nginxinc/nginx-one-workshops>.

Diff for: nginx/api-gateway/README.md

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# NGINX API Gateway Demo
2+
3+
## Overview
4+
5+
This demo uses Terraform to automate the setup of an NGINX API gateway pseudo-production environment that includes a mock API backend database.
6+
7+
## Requirements
8+
9+
### Terraform
10+
11+
This demo has been developed and tested with Terraform `0.13` through `1.1.5`.
12+
13+
Instructions on how to install Terraform can be found in the [Terraform website](https://www.terraform.io/downloads.html).
14+
15+
### AWS R53
16+
17+
You will need to create R53 hosted zone beforehand. Make sure you own the domain you are using through the R53 hosted zone or you risk running into DNS issues. You should specify the R53 hosted zone `id` as well as a FQDN for the NGINX Plus API gateway and backend API in the corresponding Terraform variables.
18+
19+
## Deployment
20+
21+
To use the provided Terraform scripts, you need to:
22+
23+
1. Export your AWS credentials as environment variables (or alternatively, tweak the AWS provider in [`terraform/provider.tf`](terraform/provider.tf)).
24+
2. Set up default values for variables missing a value in [`terraform/variables.tf`](terraform/variables.tf) (you can find example values commented out in the file). Alternatively, you can input those variables at runtime (beware of dictionary values if you do the latter).
25+
26+
Once you have configured your Terraform environment, you can either:
27+
28+
* Run [`./setup.sh`](setup.sh) to initialize the AWS Terraform provider and start a Terraform deployment on AWS.
29+
* Run `terraform init` and `terraform apply`.
30+
31+
And finally, once you are done playing with the demo, you can destroy the AWS infrastructure by either:
32+
33+
* Run [`./cleanup.sh`](cleanup.sh) to destroy your Terraform deployment.
34+
* Run `terraform destroy`.
35+
36+
## Demo Overview
37+
38+
You will find a series of NGINX configuration files in the [`nginx_api_gateway_config`](nginx_api_gateway_config/) folder. The folder is divided into individual steps, meant to be copied into their respective directory in order. By default, the folder is uploaded to your NGINX API gateway instance.
39+
40+
Do note that you will have to replace the `<backend-api-fqdn>` placeholder value found in the API backends NGINX configuration file in Step 3 with the corresponding value you used when deploying the Terraform environment (see [`nginx_api_gateway_config/step_3/api_backends.conf`](nginx_api_gateway_config/step_3/api_backends.conf) for more details).
41+
42+
A deployment script to help you copy the configuration files, [`deploy.sh`](nginx_api_gateway_config/deploy.sh), is also provided. To run the script, use the step number as a parameter, e.g. `./deploy.sh 1` for step 1. You might need to make the deployment script executable by running `sudo chmod +x deploy.sh`.
43+
44+
### Step 1 -> Define the entry point of the NGINX API gateway
45+
46+
To deploy:
47+
48+
`./deploy.sh 1`
49+
50+
To test:
51+
52+
`curl -s http://localhost:8080`
53+
54+
Expected response:
55+
56+
```html
57+
<html>
58+
<head><title>400 Bad Request</title></head>
59+
<body>
60+
<center><h1>400 Bad Request</h1></center>
61+
<hr><center>nginx/1.19.5</center>
62+
</body>
63+
</html>
64+
```
65+
66+
### Step 2 -> Define default JSON error codes
67+
68+
To deploy:
69+
70+
`./deploy.sh 2`
71+
72+
To test:
73+
74+
`curl -s http://localhost:8080 | jq`
75+
76+
Expected response:
77+
78+
```json
79+
{"status":400,"message":"Bad request"}
80+
```
81+
82+
To test (headers):
83+
84+
`curl -sI http://localhost:8080`
85+
86+
Expected response:
87+
88+
```text
89+
HTTP/1.1 400 Bad Request
90+
...
91+
```
92+
93+
### Step 3 -> Define the API endpoints and upstream/backend servers
94+
95+
To deploy:
96+
97+
`./deploy.sh 3`
98+
99+
To test:
100+
101+
`curl -s http://localhost:8080/api/f1/drivers/alonso | jq`
102+
103+
Expected response:
104+
105+
```json
106+
{
107+
"MRData": {
108+
"xmlns": "http://ergast.com/mrd/1.5",
109+
"series": "f1",
110+
"url": "http://ergast.com/api/f1/drivers/alonso",
111+
"limit": "30",
112+
"offset": "0",
113+
"total": "1",
114+
"DriverTable": {
115+
"driverId": "alonso",
116+
"Drivers": [
117+
{
118+
"driverId": "alonso",
119+
"permanentNumber": "14",
120+
"code": "ALO",
121+
"url": "http://en.wikipedia.org/wiki/Fernando_Alonso",
122+
"givenName": "Fernando",
123+
"familyName": "Alonso",
124+
"dateOfBirth": "1981-07-29",
125+
"nationality": "Spanish"
126+
}
127+
]
128+
}
129+
}
130+
}
131+
```
132+
133+
### Step 4 -> Enable rate limiting
134+
135+
To deploy:
136+
137+
`./deploy.sh 4`
138+
139+
To test (run multiple times in quick succession):
140+
141+
`curl -s http://localhost:8080/api/f1/drivers/alonso | jq`
142+
143+
Expected response:
144+
145+
```json
146+
{"status":429,"message":"API rate limit exceeded"}
147+
```
148+
149+
### Step 5 -> Set up API Key authentication
150+
151+
To deploy:
152+
153+
`./deploy.sh 5`
154+
155+
To test (unauthorized requests):
156+
157+
`curl -s http://localhost:8080/api/f1/drivers/alonso | jq`
158+
159+
Expected response (unauthorized requests):
160+
161+
```json
162+
{"status":401,"message":"Unauthorized"}
163+
```
164+
165+
To test (authorized requests):
166+
167+
`curl -sH "apikey: 7B5zIqmRGXmrJTFmKa99vcit" http://localhost:8080/api/f1/drivers/alonso | jq`
168+
169+
Expected response (authorized requests):
170+
171+
```json
172+
{"MRData": {
173+
"xmlns": "http://ergast.com/mrd/1.4",
174+
"series": "f1",
175+
"url": "http://ergast.com/api/f1/drivers/alonso",
176+
...
177+
}}
178+
```
179+
180+
### Step 6 -> Set up JSON body validation using NJS
181+
182+
To deploy:
183+
184+
`./deploy.sh 6`
185+
186+
To test (incorrect JSON):
187+
188+
`curl -sH "apikey: 7B5zIqmRGXmrJTFmKa99vcit" -i -X POST -d 'garbage123' http://localhost:8080/api/f1/seasons`
189+
190+
Expected response (incorrect JSON):
191+
192+
```text
193+
HTTP/1.1 415 Unsupported Media Type
194+
```
195+
196+
To test (correct JSON):
197+
198+
`curl -sH "apikey: 7B5zIqmRGXmrJTFmKa99vcit" -i -X POST -d '{"season":"2020"}' http://localhost:8080/api/f1/seasons | jq`
199+
200+
Expected response (correct JSON):
201+
202+
```text
203+
HTTP/1.1 200 OK
204+
```

Diff for: nginx/api-gateway/cleanup.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cd terraform \
2+
&& terraform destroy -auto-approve \
3+
&& rm -f terraform.tfstate terraform.tfstate.backup \
4+
&& rm -rf .terraform

Diff for: nginx/api-gateway/nginx_api_gateway_config/deploy.sh

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
if [ -z $1 ]; then
4+
echo "You need to pass a step number"
5+
exit 1;
6+
fi
7+
8+
if (($1 < 1 || $1 > 8)); then
9+
echo "Only steps 1 through 8 exist"
10+
exit 1;
11+
fi
12+
13+
sudo cp -r step_$1/* /etc/nginx
14+
sudo nginx -s reload
15+
16+
if [ $? = 0 ]; then
17+
echo "NGINX successfully reloaded"
18+
fi
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
server {
2+
listen 8080;
3+
4+
include conf.d/my_apis/*.conf;
5+
6+
location / {
7+
return 400;
8+
}
9+
10+
default_type application/json;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error_page 400 = @400;
2+
location @400 {
3+
return 400 '{"status":400,"message":"Bad request"}\n';
4+
}
5+
error_page 401 = @401;
6+
location @401 {
7+
return 401 '{"status":401,"message":"Unauthorized"}\n';
8+
}
9+
error_page 403 = @403;
10+
location @403 {
11+
return 403 '{"status":403,"message":"Forbidden"}\n';
12+
}
13+
error_page 405 = @405;
14+
location @405 {
15+
return 405 '{"status":405,"message":"Method not allowed"}\n';
16+
}
17+
error_page 429 = @429;
18+
location @429 {
19+
return 429 '{"status":429,"message":"API rate limit exceeded"}\n';
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
upstream f1-admin {
2+
server <backend-api-fqdn>;
3+
}
4+
5+
upstream f1-data {
6+
server <backend-api-fqdn>:8000;
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
location /api/f1/ {
2+
location = /api/f1/seasons {
3+
proxy_pass http://f1-admin;
4+
}
5+
6+
location ~ /api/f1/[12][0-9]+ {
7+
proxy_pass http://f1-data;
8+
}
9+
10+
location /api/f1/drivers {
11+
proxy_pass http://f1-data;
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
limit_req_zone $remote_addr zone=perip:1m rate=1r/s;
2+
3+
server {
4+
listen 8080;
5+
6+
include conf.d/my_apis/*.conf;
7+
8+
location / {
9+
return 400;
10+
}
11+
12+
default_type application/json;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
location /api/f1/ {
2+
limit_req zone=perip nodelay;
3+
limit_req_status 429;
4+
5+
location = /api/f1/seasons {
6+
proxy_pass http://f1-admin;
7+
}
8+
9+
location ~ /api/f1/[12][0-9]+ {
10+
proxy_pass http://f1-data;
11+
}
12+
13+
location /api/f1/drivers {
14+
proxy_pass http://f1-data;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
map $http_apikey $api_client_name {
2+
"7B5zIqmRGXmrJTFmKa99vcit" "client_one";
3+
"QzVV6y1EmQFbbxOfRCwyJs35" "client_two";
4+
default "";
5+
}

0 commit comments

Comments
 (0)