Merge 9fa4be55037ccf047e12bee4df73dc5719ee595f into 35e35ecd57c64eaca5f30c81e90223a4f5d45737

This commit is contained in:
Shahbaz Nazir 2018-09-12 12:59:13 +00:00 committed by GitHub
commit 2fe17c453b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 0 deletions

View File

@ -0,0 +1,52 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: openresty-instance-1-dep
spec:
replicas: 1
template:
metadata:
labels:
app: openresty-instance-1-dep
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx-openresty
image: bigchaindb/nginx_3scale:unstable
imagePullPolicy: Always
env:
- name: THREESCALE_PORTAL_ENDPOINT
valueFrom:
secretKeyRef:
name: apicast-secret
key: portal-endpoint
- name: RESOLVER
valueFrom:
configMapKeyRef:
name: vars
key: cluster-dns-server-ip
- name: APICAST_LOG_LEVEL
valueFrom:
configMapKeyRef:
name: apicast-config
key: api-log-level
- name: APICAST_MANAGEMENT_API
valueFrom:
configMapKeyRef:
name: apicast-config
key: mgmt-api-mode
- name: BIGCHAINDB_BACKEND_HOST
valueFrom:
configMapKeyRef:
name: vars
key: bdb-instance-name
- name: BIGCHAINDB_API_PORT
valueFrom:
configMapKeyRef:
name: vars
key: bigchaindb-api-port
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 8090
protocol: TCP

View File

@ -0,0 +1,25 @@
apiVersion: v1
kind: Service
metadata:
name: openresty-instance-1
namespace: default
labels:
name: openresty-instance-1
annotations:
# NOTE: the following annotation is a beta feature and
# only available in GCE/GKE and Azure as of now
# Ref: https://kubernetes.io/docs/tutorials/services/source-ip/
service.beta.kubernetes.io/external-traffic: OnlyLocal
spec:
selector:
app: openresty-instance-1-dep
ports:
- port: 8080
targetPort: 8080
name: apicast-svc
- port: 8090
targetPort: 8090
name: apicast-mgmt
protocol: TCP
type: ClusterIP
clusterIP: None

View File

@ -0,0 +1,16 @@
FROM openresty/openresty:xenial
LABEL maintainer "dev@bigchaindb.com"
WORKDIR /opt/apicast
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get autoremove \
&& apt-get clean \
&& apt-get install wget
COPY nginx_openresty_entrypoint.bash /
# The following ports are the values we use to run the NGINX+3scale container.
# 80 for http, 8080 for the 3scale api, 8888 for health-check, 27017 for
# MongoDB
EXPOSE 8080 8090 8888
ENTRYPOINT ["/nginx_openresty_entrypoint.bash"]

View File

@ -0,0 +1,60 @@
# nginx_3scale agent
nginx_3scale agent is a module that is responsible for providing authentication,
authorization and metering of BigchainDB API users, by communicating with 3scale.
We use the openresty for this, which is nginx bundled with lua libraries.
More information at their [website](openresty.org/en)
It validates the tokens sent by users in HTTP headers.
The user tokens map directly to the Application Plan specified in 3scale.
## Build and Push the Latest Container
Use the `docker_build_and_push.bash` script to build the latest docker image
and upload it to Docker Hub.
Ensure that the image tag is updated to a new version number to properly
reflect any changes made to the container.
## Working
* We define a [lua module](./nginx.lua.template) and
custom hooks (lua functions to be executed at certain phases of the nginx
request processing lifecycle) to authenticate an API request.
* Download the template available from 3scale which pre-defines all the
rules defined using the 3scale UI for monitoring, and the basic nginx
configuration.
* We heavily modify these templates to add our custom functionality.
* The nginx_3scale image reads the environment variables and accordingly
creates the nginx.conf and nginx.lua files from the templates.
* Every request calls the `_M.access()` function. This function extracts the
`app_id` and `app_key` from the HTTP request headers and forwards it to
3scale to see if a request is allowed to be forwarded to the BigchainDB
backend. The request also contains the
various parameters that one would like to set access policies on. If the
`app_id` and `app_key` is successful, the access rules for the parameters
passed with the request are checked to see if the request can pass through.
For example, we can send a parameter, say `request_body_size`, to the 3scale
auth API. If we have defined a rule in the 3scale dashboard to drop
`request_body_size` above a certain threshold, the authorization will fail
even if the `app_id` and `app_key` are valid.
* A successful response from the auth API causes the request to be proxied to
the backend. After a backend response, the `_M.post_action_content` hook is
called. We calculate details about all the metrics we are interested in and
form a payload for the 3scale reporting API. This ensures that we update
parameters of every metric defined in the 3scale UI after every request.
* Note: We do not cache the keys in nginx so that we can validate every request
with 3scale and apply plan rules immediately. We can add auth caching to
improve performance, and in case we move to a fully post-paid billing model.
* Refer to the references made in the [lua module](./nginx.lua.template) for
more details about how nginx+lua+3scale works
* For HTTPS support, we also need to add the signed certificate and the
corresponding private key to the folder
`/usr/local/openresty/nginx/conf/ssl/`. Name the pem-encoded certificate as
`cert.pem` and the private key as `cert.key`.

View File

@ -0,0 +1,5 @@
#!/bin/bash
docker build -t bigchaindb/nginx_3scale:unstable .
docker push bigchaindb/nginx_3scale:unstable

View File

@ -0,0 +1,37 @@
#!/bin/bash
set -euo pipefail
BASE_DIR=$(pwd)
APICAST_RELEASE="3.1.0"
BASE_GIT_URL="https://github.com/3scale/apicast/archive"
# Set Default config
export APICAST_CONFIGURATION_LOADER="boot" # Overriding apicast default lazy config loader
export APICAST_MANAGEMENT_API="debug" # Overriding apicast default fo 'status' mode to be
# able to update bigchaindb backen service endpoint
# Sanity Check
if [[ -z "${THREESCALE_PORTAL_ENDPOINT:?THREESCALE_PORTAL_ENDPOINT not specified. Exiting!}" || \
-z "${BIGCHAINDB_BACKEND_HOST:?BIGCHAINDB_BACKEND_HOST not specified. Exiting!}" || \
-z "${BIGCHAINDB_API_PORT:?BIGCHAINDB_API_PORT not specified. Exiting!}" ]]; then
exit 1
fi
export THREESCALE_PORTAL_ENDPOINT=`printenv THREESCALE_PORTAL_ENDPOINT`
# Print Current Configs
echo "Apicast Release: ${APICAST_RELEASE}"
echo "Apicast Download URL: ${BASE_GIT_URL}"
echo "APICAST_CONFIGURATION_LOADER: ${APICAST_CONFIGURATION_LOADER}"
echo "BIGCHAINDB_BACKEND_HOST: ${BIGCHAINDB_BACKEND_HOST}"
echo "BIGCHAINDB_API_PORT: ${BIGCHAINDB_API_PORT}"
# Download and Install Apicast
wget "${BASE_GIT_URL}/v${APICAST_RELEASE}.tar.gz"
tar -xvzf "v${APICAST_RELEASE}.tar.gz"
eval luarocks make apicast-${APICAST_RELEASE}/apicast/*.rockspec --tree /usr/local/openresty/luajit
# Start nginx
echo "INFO: starting nginx..."
exec apicast-${APICAST_RELEASE}/apicast/bin/apicast -b -e production -v -v -v