Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
feat(plugin): add proxywasm plugin (#284)
Browse files Browse the repository at this point in the history
* feat(plugin): add `proxywasm` plugin

The `proxywasm` plugin is a WASM Filter following the ProxyWasm ABI Specification using the proxywasm go sdk

This allows extensibility with any reverse proxy who implements the ProxyWasm ABI Specification.

The current WASM Filter was successfully tested with APISIX, Envoy, Nginx with ngx_wasm_module from Kong and Istio.

Fixes #145
  • Loading branch information
acouvreur committed Oct 2, 2024
1 parent 54bc622 commit 3891027
Show file tree
Hide file tree
Showing 57 changed files with 2,164 additions and 2,891 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Go",
"image": "mcr.microsoft.com/devcontainers/go:1.22-bookworm",
"image": "mcr.microsoft.com/devcontainers/go:1.22",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "lts"
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
149 changes: 148 additions & 1 deletion .github/workflows/plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,151 @@ jobs:
run: docker load --input /tmp/caddy.tar

- name: Test ${{ matrix.provider }}
run: cd plugins/caddy/e2e/${{ matrix.provider }} && bash ./run.sh
run: cd plugins/caddy/e2e/${{ matrix.provider }} && bash ./run.sh

build-proxywasm:
name: Build ProxyWasm Plugin once and share it to ProxyWasm E2E jobs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup TinyGo
uses: acifani/setup-tinygo@v2
with:
tinygo-version: '0.31.2'

- name: Build
run: make proxywasm

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: proxywasm-plugin-wasm
path: ./plugins/proxywasm/sablierproxywasm.wasm

proxywasm_apisix_e2e:
name: Run Sablier E2E tests for Proxywasm middleware on Apache APISIX
runs-on: ubuntu-latest
needs:
- build
- build-proxywasm
strategy:
fail-fast: false
matrix:
provider: [ docker ] #, docker_swarm, kubernetes]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: 1.22
cache-dependency-path: |
go.sum
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: sablier-image-tar
path: /tmp

- name: Load Docker image
run: docker load --input /tmp/sablier.tar

- name: Download Proxywasm artifact
uses: actions/download-artifact@v4
with:
name: proxywasm-plugin-wasm
path: ./plugins/proxywasm

- name: Test ${{ matrix.provider }}
run: cd plugins/proxywasm/e2e/apacheapisix/${{ matrix.provider }} && bash ./run.sh

proxywasm_envoy_e2e:
name: Run Sablier E2E tests for Proxywasm middleware on Envoy
runs-on: ubuntu-latest
needs:
- build
- build-proxywasm
strategy:
fail-fast: false
matrix:
provider: [ docker ] #, docker_swarm, kubernetes]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: 1.22
cache-dependency-path: |
go.sum
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: sablier-image-tar
path: /tmp

- name: Load Docker image
run: docker load --input /tmp/sablier.tar

- name: Download Proxywasm artifact
uses: actions/download-artifact@v4
with:
name: proxywasm-plugin-wasm
path: ./plugins/proxywasm

- name: Test ${{ matrix.provider }}
run: cd plugins/proxywasm/e2e/envoy/${{ matrix.provider }} && bash ./run.sh

proxywasm_nginx_e2e:
name: Run Sablier E2E tests for Proxywasm middleware on Nginx
runs-on: ubuntu-latest
needs:
- build
- build-proxywasm
strategy:
fail-fast: false
matrix:
provider: [ docker ] #, docker_swarm, kubernetes]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: 1.22
cache-dependency-path: |
go.sum
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: sablier-image-tar
path: /tmp

- name: Load Docker image
run: docker load --input /tmp/sablier.tar

- name: Download Proxywasm artifact
uses: actions/download-artifact@v4
with:
name: proxywasm-plugin-wasm
path: ./plugins/proxywasm

- name: Test ${{ matrix.provider }}
run: cd plugins/proxywasm/e2e/nginx/${{ matrix.provider }} && bash ./run.sh
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
sablier.yaml
./plugins/traefik/e2e/kubeconfig.yaml
node_modules
.DS_Store
.DS_Store
*.wasm
kubeconfig.yaml
15 changes: 15 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
linters:
enable:
- dupword # Checks for duplicate words in the source code.
- goimports
- gosec
- gosimple
- govet
- importas
- ineffassign
- misspell
- revive
- staticcheck
- typecheck
- unconvert
- unused
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ caddy:
docker build -t caddy:local plugins/caddy

release: $(PLATFORMS)

proxywasm:
go generate ./plugins/proxywasm
tinygo build -ldflags "-X 'main.Version=$(VERSION)'" -o ./plugins/proxywasm/sablierproxywasm.wasm -scheduler=none -target=wasi ./plugins/proxywasm
cp ./plugins/proxywasm/sablierproxywasm.wasm ./sablierproxywasm_$(VERSION).wasm

.PHONY: release $(PLATFORMS)

LAST = 0.0.0
Expand Down
4 changes: 1 addition & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
![Latest Build](https://img.shields.io/github/actions/workflow/status/acouvreur/sablier/build.yml?style=flat-square&branch=main)![Go Report](https://goreportcard.com/badge/github.com/acouvreur/sablier?style=flat-square) ![Go Version](https://img.shields.io/github/go-mod/go-version/acouvreur/sablier?style=flat-square) ![Latest Release](https://img.shields.io/github/release/acouvreur/sablier/all.svg?style=flat-square)

*This website is still a work in progress and is based on the **beta** branch version*

# Sablier - Scale to Zero

Sablier is a **free** and **open-source** software that can scale your workloads on demand.
Expand All @@ -19,7 +17,7 @@ Which allows you to start your containers on demand and shut them down automatic

## Glossary

I'll use these terms in order to be provider agnostic.
I'll use these terms in order to be provider-agnostic.

- **Session**: A Session is a set of **instances**
- **Instance**: An instance is either a docker container, docker swarm service, kubernetes deployment or kubernetes statefulset
Expand Down
16 changes: 10 additions & 6 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@
- [Versioning](/versioning)
- **Providers**
- [Overview](/providers/overview)
- [Docker](/providers/docker)
- [Docker Swarm](/providers/docker_swarm)
- [Kubernetes](/providers/kubernetes)
- [<img src="assets/img/docker.svg" height=24px width=24px />Docker](/providers/docker)
- [<img src="assets/img/docker_swarm.png" height=24px width=24px />Docker Swarm](/providers/docker_swarm)
- [<img src="assets/img/kubernetes.png" height=24px width=24px />Kubernetes](/providers/kubernetes)
- **Reverse Proxy Plugins**
- [Overview](/plugins/overview)
- [Traefik](/plugins/traefik)
- [Nginx](/plugins/nginx)
- [Caddy](/plugins/caddy)
- [<img src="assets/img/apacheapisix.png" height=24px width=24px />Apache APISIX](/plugins/apacheapisix)
- [<img src="assets/img/caddy.png" height=24px width=24px />Caddy](/plugins/caddy)
- [<img src="assets/img/envoy.png" height=24px width=24px />Envoy](/plugins/envoy)
- [<img src="assets/img/istio.png" height=24px width=24px />Istio](/plugins/istio)
- [<img src="assets/img/nginx.svg" height=24px width=24px />Nginx (NJS)](/plugins/nginx)
- [<img src="assets/img/nginx.svg" height=24px width=24px />Nginx (ProxyWasm)](/plugins/nginx_proxywasm)
- [<img src="assets/img/traefik.png" height=24px /> Traefik](/plugins/traefik)
- **Guides**
- [Overview](/guides/overview)
- [VSCode Server with Traefik and Kubernetes](/guides/code-server-traefik-kubernetes.md)
Expand Down
Binary file added docs/assets/img/apacheapisix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/caddy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/docker_swarm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/envoy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/istio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/kubernetes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/assets/img/nginx.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/traefik.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions docs/plugins/apacheapisix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Apache APISIX Plugin

The Apache APISIX Plugin is a WASM Plugin written with the Proxy Wasm SDK.

## Provider compatibility grid

| Provider | Dynamic | Blocking |
|-----------------------------------------|:-------:|:--------:|
| [Docker](/providers/docker) |||
| [Docker Swarm](/providers/docker_swarm) |||
| [Kubernetes](/providers/kubernetes) |||

## Install the plugin to Apache APISIX

```yaml
wasm:
plugins:
- name: proxywasm_sablier_plugin
priority: 7997
file: /wasm/sablierproxywasm.wasm # Downloaded WASM Filter path
```
## Configuration
You can have the following configuration:
```yaml
routes:
- uri: "/"
plugins:
proxywasm_sablier_plugin:
conf: '{ "sablier_url": "sablier:10000", "group": ["my-group"], "session_duration": "1m", "dynamic": { "display_name": "Dynamic Whoami" } }'
```
48 changes: 48 additions & 0 deletions docs/plugins/envoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Envoy Plugin

The Envoy Plugin is a WASM Plugin written with the Proxy Wasm SDK.

## Provider compatibility grid

| Provider | Dynamic | Blocking |
|-----------------------------------------|:-------:|:--------:|
| [Docker](/providers/docker) |||
| [Docker Swarm](/providers/docker_swarm) |||
| [Kubernetes](/providers/kubernetes) |||

## Configuration

You can have the following configuration:

```yaml
http_filters:
- name: sablier-wasm-whoami-dynamic
disabled: true
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "sablier-wasm-whoami-dynamic"
root_id: "sablier-wasm-whoami-dynamic"
configuration:
"@type": "type.googleapis.com/google.protobuf.StringValue"
value: |
{
"sablier_url": "sablier:10000",
"cluster": "sablier",
"names": ["docker_classic_e2e-whoami-1"],
"session_duration": "1m",
"dynamic": {
"display_name": "Dynamic Whoami",
"theme": "hacker-terminal"
}
}
vm_config:
runtime: "envoy.wasm.runtime.v8"
vm_id: "vm.sablier.sablier-wasm-whoami-dynamic"
code:
local:
filename: "/etc/sablierproxywasm.wasm"
configuration: { }
```
45 changes: 45 additions & 0 deletions docs/plugins/istio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Istio Plugin

The Istio Plugin is a WASM Plugin written with the Proxy Wasm SDK.

## Provider compatibility grid

| Provider | Dynamic | Blocking |
|-----------------------------------------|:-------:|:--------:|
| [Docker](/providers/docker) |||
| [Docker Swarm](/providers/docker_swarm) |||
| [Kubernetes](/providers/kubernetes) |||

## Configuration

You can have the following configuration:

!> This only works for ingress gateways.
!> Attaching this filter to a side-car would not work because the side-car itself gets shutdown on scaling to zero.

```yaml
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: sablier-wasm-whoami-dynamic
namespace: istio-system
spec:
selector:
matchLabels:
istio: ingressgateway
url: file:///opt/filters/sablierproxywasm.wasm/..data/sablierproxywasm.wasm
# Use https://istio.io/latest/docs/reference/config/proxy_extensions/wasm-plugin/#WasmPlugin-TrafficSelector
# To specify which service to apply this filter only
phase: UNSPECIFIED_PHASE
pluginConfig:
{
"sablier_url": "sablier.sablier-system.svc.cluster.local",
"cluster": "outbound|10000||sablier.sablier-system.svc.cluster.local",
"names": [ "deployment_default_whoami_1" ],
"session_duration": "1m",
"dynamic": {
"display_name": "Dynamic Whoami",
"theme": "hacker-terminal"
}
}
```
Loading

0 comments on commit 3891027

Please sign in to comment.