diff --git a/agones/src/lib.rs b/agones/src/lib.rs
index 0c94cdecab..9bcdab615f 100644
--- a/agones/src/lib.rs
+++ b/agones/src/lib.rs
@@ -354,7 +354,7 @@ pub fn quilkin_container(
liveness_probe: Some(Probe {
http_get: Some(HTTPGetAction {
path: Some("/live".into()),
- port: IntOrString::Int(9091),
+ port: IntOrString::Int(8000),
..Default::default()
}),
initial_delay_seconds: Some(3),
@@ -364,7 +364,7 @@ pub fn quilkin_container(
readiness_probe: Some(Probe {
http_get: Some(HTTPGetAction {
path: Some("/ready".into()),
- port: IntOrString::Int(9091),
+ port: IntOrString::Int(8000),
..Default::default()
}),
initial_delay_seconds: Some(3),
diff --git a/agones/src/sidecar.rs b/agones/src/sidecar.rs
index 622b93bcac..eb5f1cab27 100644
--- a/agones/src/sidecar.rs
+++ b/agones/src/sidecar.rs
@@ -90,7 +90,7 @@ clusters:
let mut gs = game_server();
// reset ports to point at the Quilkin sidecar
- gs.spec.ports[0].container_port = 7000;
+ gs.spec.ports[0].container_port = 7777;
gs.spec.ports[0].container = Some("quilkin".into());
// set the gameserver container to the simple-game-server container.
diff --git a/agones/src/xds.rs b/agones/src/xds.rs
index 2b952a1cdc..f763d63866 100644
--- a/agones/src/xds.rs
+++ b/agones/src/xds.rs
@@ -275,7 +275,7 @@ filters:
.to_vec();
let mut container = quilkin_container(client, Some(args), None);
container.ports = Some(vec![ContainerPort {
- container_port: 7000,
+ container_port: 7777,
..Default::default()
}]);
let labels = BTreeMap::from([("role".to_string(), "xds".to_string())]);
@@ -318,8 +318,8 @@ filters:
selector: Some(labels),
ports: Some(vec![ServicePort {
protocol: Some("TCP".into()),
- port: 80,
- target_port: Some(IntOrString::Int(7000)),
+ port: 7800,
+ target_port: Some(IntOrString::Int(7800)),
..Default::default()
}]),
..Default::default()
@@ -350,7 +350,7 @@ filters:
let config = r#"
version: v1alpha1
management_servers:
- - address: http://quilkin-manage-agones:80
+ - address: http://quilkin-manage-agones:7800
"#;
let config_map = config_maps
@@ -362,12 +362,12 @@ management_servers:
quilkin_container(client, Some(vec!["proxy".into()]), Some(mount_name.into()));
// we'll use a host port, since spinning up a load balancer takes a long time.
- // we know that port 7000 is open because this is an Agones cluster and it has associated
+ // we know that port 7777 is open because this is an Agones cluster and it has associated
// firewall rules , and even if we conflict with a GameServer
// the k8s scheduler will move us to another node.
let host_port: u16 = 7005;
container.ports = Some(vec![ContainerPort {
- container_port: 7000,
+ container_port: 7777,
host_port: Some(host_port as i32),
protocol: Some("UDP".into()),
..Default::default()
diff --git a/build/Makefile b/build/Makefile
index 6c30750900..7130e3b0c0 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -108,6 +108,7 @@ test-docs:
cargo doc --workspace --no-deps && cd docs && mdbook build --dest-dir /tmp/docs/book && \
cp -r "$(CARGO_TARGET_DIR)/doc" /tmp/docs/api && \
rm /tmp/docs/book/print.html && \
+ echo "" > /tmp/docs/book/print.html && \
htmltest -c /workspace/docs/htmltest.yaml /tmp/docs'
# Build all binaries, images and related artifacts
diff --git a/docs/book.toml b/docs/book.toml
index 2f958155f1..a5819731cb 100644
--- a/docs/book.toml
+++ b/docs/book.toml
@@ -29,4 +29,7 @@ use_env = true
[preprocessor.variables.variables]
+[build]
+create-missing = false
+
[output.html]
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
index 804393bd50..d35b9dd27a 100644
--- a/docs/src/SUMMARY.md
+++ b/docs/src/SUMMARY.md
@@ -1,38 +1,42 @@
-# Summary
+[Introduction](./introduction.md)
+[Installation](./installation.md)
+[FAQ](./faq.md)
-- [Introduction](./introduction.md)
-- [Quickstart](./quickstart.md)
- - [Netcat](./quickstarts/netcat.md)
- - [Agones + Xonotic (Sidecar)](./quickstarts/agones-xonotic-sidecar.md)
- - [Agones + Xonotic (xDS)](./quickstarts/agones-xonotic-xds.md)
-- [Usage](./using.md)
- - [File Configuration](./file-configuration.md)
-- [Integrations](./integrations.md)
-- [Proxy Mode](./proxy-mode.md)
- - [Concepts](proxy/concepts.md)
- - [Filters](./filters.md)
- - [Capture](proxy/filters/capture.md)
- - [Compress](proxy/filters/compress.md)
- - [Concatenate Bytes](proxy/filters/concatenate_bytes.md)
- - [Debug](proxy/filters/debug.md)
- - [Drop](proxy/filters/drop.md)
- - [Firewall](proxy/filters/firewall.md)
- - [Load Balancer](proxy/filters/load_balancer.md)
- - [Local Rate Limit](proxy/filters/local_rate_limit.md)
- - [Match](proxy/filters/match.md)
- - [Pass](proxy/filters/pass.md)
- - [Timestamp](proxy/filters/timestamp.md)
- - [Token Router](proxy/filters/token_router.md)
- - [Writing Custom Filters](proxy/filters/writing_custom_filters.md)
- - [Metrics](proxy/metrics.md)
- - [Maxmind](proxy/maxmind.md)
-- [xDS Management API](./xds.md)
- - [Built-in xDS Providers](./xds/builtin.md)
- - [Filesytem](./xds/providers/filesystem.md)
- - [Agones](./xds/providers/agones.md)
- - [Metrics](./xds/metrics.md)
-- [Administration](./admin.md)
-- [Client SDKs](./sdks.md)
- - [Unreal Engine](./sdks/unreal-engine.md)
-- [Examples](./examples.md)
-- [FAQ](./faq.md)
+# Quickstart Guides
+- [Netcat](./deployment/quickstarts/netcat.md)
+- [Agones + Xonotic (Sidecar)](./deployment/quickstarts/agones-xonotic-sidecar.md)
+- [Agones + Xonotic (xDS)](./deployment/quickstarts/agones-xonotic-xds.md)
+
+# Services
+- [Proxy](./services/proxy.md)
+ - [Filters](./services/proxy/filters.md)
+ - [Capture](./services/proxy/filters/capture.md)
+ - [Compress](./services/proxy/filters/compress.md)
+ - [Concatenate Bytes](./services/proxy/filters/concatenate_bytes.md)
+ - [Debug](./services/proxy/filters/debug.md)
+ - [Drop](./services/proxy/filters/drop.md)
+ - [Firewall](./services/proxy/filters/firewall.md)
+ - [Load Balancer](./services/proxy/filters/load_balancer.md)
+ - [Local Rate Limit](./services/proxy/filters/local_rate_limit.md)
+ - [Match](./services/proxy/filters/match.md)
+ - [Pass](./services/proxy/filters/pass.md)
+ - [Timestamp](./services/proxy/filters/timestamp.md)
+ - [Token Router](./services/proxy/filters/token_router.md)
+ - [Writing Custom Filters](./services/proxy/filters/writing_custom_filters.md)
+ - [Metrics](./services/proxy/metrics.md)
+
+---
+
+- [Control Plane](./services/xds.md)
+ - [Metrics](./services/xds/metrics.md)
+ - [Providers]()
+ - [Agones](./services/xds/providers/agones.md)
+ - [Filesystem](./services/xds/providers/filesystem.md)
+
+# SDKs
+- [Unreal Engine](./sdks/unreal-engine.md)
+
+# Deployment
+- [Administration](./deployment/admin.md)
+- [Architecture Examples](./deployment/examples.md)
+- [Configuration](./deployment/configuration.md)
diff --git a/docs/src/admin.md b/docs/src/deployment/admin.md
similarity index 51%
rename from docs/src/admin.md
rename to docs/src/deployment/admin.md
index 152386c710..90bd1e6c0a 100644
--- a/docs/src/admin.md
+++ b/docs/src/deployment/admin.md
@@ -1,41 +1,56 @@
-# Administration Interface
+# Administration
+
+| services | ports | Protocol |
+|----------|-------|-----------|
+| Administration | 8000 | HTTP (IPv4 OR IPv6) |
+
+## Logging
+By default Quilkin will log `INFO` level events, you can change this by setting
+the `RUST_LOG` environment variable. See [`log` documentation][log-docs] for
+more advanced usage.
+
+> If you are debugging Quilkin set the `RUST_LOG` environemnt variable to `quilkin=trace`, to filter trace level
+> logging to only Quilkin components.
+
+## HTTP API
Quilkin exposes an HTTP interface to query different aspects of the server.
> It is assumed that the administration interface will only ever be able to be accessible on `localhost`.
-By default, the administration interface is bound to `[::]:9091`, but it can be configured by the command line flag
-`--admin-address` or through the [proxy configuration file](./file-configuration.md), like so:
+By default, the administration interface is bound to `[::]:8000`, but it can be configured by the command line flag
+`--admin-address` or through the [configuration file](./configuration.md), like so:
```yaml
admin:
address: [::]:9095
```
+
## Endpoints
The admin interface provides the following endpoints:
### /live
-This provides a liveness probe endpoint, most commonly used in
+This provides a liveness probe endpoint, most commonly used in
[Kubernetes based systems](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-command).
Will return an HTTP status of 200 when all health checks pass.
### /ready
-This provides a readiness probe endpoint, most commonly used in
+This provides a readiness probe endpoint, most commonly used in
[Kubernetes based systems](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes).
-Depending on whether Quilkin is run in Proxy mode i.e. `quilkin proxy`, vs an xDS provider mode, such as `quilkin
-manage agones`, will dictate how readiness is calculated:
+Depending on whether Quilkin is run in Proxy mode i.e. `quilkin proxy`, vs an xDS provider mode, such as `quilkin
+manage agones`, will dictate how readiness is calculated:
#### Proxy Mode
-Will return an HTTP status of 200 when there is at least one endpoint to send data to. This is primarily to ensure
-that new proxies that have yet to get configuration information from an [xDS server](./xds.md) aren't send data
-until they are fully populated.
+Will return an HTTP status of 200 when there is at least one endpoint to send data to. This is primarily to ensure
+that new proxies that have yet to get configuration information from an [xDS server](../services/xds.md) aren't send data
+until they are fully populated.
#### xDS Provider Mode
@@ -45,9 +60,9 @@ Will return an HTTP status of 200 when all health checks pass.
Outputs [Prometheus](https://prometheus.io/) formatted metrics for this instance.
-See the [Proxy Metrics](proxy/metrics.md) documentation for what proxy metrics are available.
+See the [Proxy Metrics](../services/proxy/metrics.md) documentation for what proxy metrics are available.
-See the [xDS Metrics](./xds/metrics.md) documentation for what xDS metrics are available.
+See the [xDS Metrics](../services/xds/metrics.md) documentation for what xDS metrics are available.
### /config
diff --git a/docs/src/file-configuration.md b/docs/src/deployment/configuration.md
similarity index 94%
rename from docs/src/file-configuration.md
rename to docs/src/deployment/configuration.md
index 3555ed88a1..834cc4a258 100644
--- a/docs/src/file-configuration.md
+++ b/docs/src/deployment/configuration.md
@@ -1,4 +1,4 @@
-# File Configuration
+# Configuration
The following is the schema and reference for a Quilkin configuration
file. See the [examples] folder for example configuration files.
@@ -11,19 +11,20 @@ environment variable.
## Static Configuration
-Example of a full configuration for `quilkin proxy` that utlisies a static Endpoint configuration:
+Example of a full configuration for `quilkin proxy` that utlisies a static
+endpoint configuration:
```yaml
-{{#include ../../examples/proxy.yaml:17:100}}
+{{#include ../../../examples/proxy.yaml:17:100}}
```
## Dynamic Configuration
-Example of a full configuration for `quilkin proxy` that utlisies a dynamic Endpoint configuration through an
-[xDS management endpoint](./xds.md):
+Example of a full configuration for `quilkin proxy` that utlisies a dynamic
+Endpoint configuration through an [xDS management endpoint](../services/xds.md):
```yaml
-{{#include ../../examples/control-plane.yaml:17:100}}
+{{#include ../../../examples/control-plane.yaml:17:100}}
```
## Json Schema
diff --git a/docs/src/integrations.md b/docs/src/deployment/examples.md
similarity index 90%
rename from docs/src/integrations.md
rename to docs/src/deployment/examples.md
index a9b3a2f03e..52182ee3c0 100644
--- a/docs/src/integrations.md
+++ b/docs/src/deployment/examples.md
@@ -6,7 +6,10 @@ each providing different capabilities and complexity tradeoffs.
Below captures several of the most useful and prevalent architectural patterns to give you inspiration
on how you can use Quilkin in your multiplayer game networking architecture.
-## Server Proxy as a Sidecar
+These [examples](https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/examples)
+as well many others are available on Github repository.
+
+## [Server Proxy as a Sidecar](https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/examples/agones-xonotic-sidecar)
```text
|
@@ -77,12 +80,12 @@ This example is the same as the above, but puts a Client Proxy between the Game
advantage of Client Proxy functionality.
* The Client Proxy may be integrated as a standalone binary, directly into the client with communication
- occurring over a localhost port or it may be possible utlise one of our [client SDKs].
+ occurring over a localhost port or it may be possible utlise one of our client SDKs such as [Unreal Engine][ue].
* The Client Proxy can now utilise filters, such as compression, without having to change the Game Client.
-* The Game Client will need to communicate to the Client Proxy what IP it should connect to when the Client is
+* The Game Client will need to communicate to the Client Proxy what IP it should connect to when the Client is
match-made with a Game Server.
-## Client Proxy to Separate Server Proxies Pools
+## [Client Proxy to Separate Server Proxies Pools](https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/examples/agones-xonotic-xds)
```text
| |
@@ -122,32 +125,32 @@ This is the most complex configuration, but enables the most reuse of Quilkin's
while also providing the most redundancy and security for your dedicated game servers.
* The Game client sends and receives packets from the Quilkin client proxy.
-* The Client Proxy may be integrated as a standalone binary, with communication occurring over a localhost port, or
- it could be integrated directly with the game client as a library, or the client could utilise one of our
+* The Client Proxy may be integrated as a standalone binary, with communication occurring over a localhost port, or
+ it could be integrated directly with the game client as a library, or the client could utilise one of our
[client SDKs] if Rust integration is not possible.
-* The Client Proxy can utilise the full set of filters, such as concatenation (for routing), compression or load
+* The Client Proxy can utilise the full set of filters, such as concatenation (for routing), compression or load
balancing, without having to change the Game Client.
-* A hosted set of Quilkin Server proxies that have public IP addresses, are connected to an
- [xDS Control Plane](./xds.md) to coordinate routing and access control to the dedicated game servers, which are
+* A hosted set of Quilkin Server proxies that have public IP addresses, are connected to an
+ [xDS Control Plane](../services/xds.md) to coordinate routing and access control to the dedicated game servers, which are
on private IP addresses.
* The Client Proxy is made aware of one or more Server proxies to connect to, possibly via their Game Client matchmaker
or another service, with an authentication token to pass to the Server proxies, such that the UDP packets can be
routed correctly to the dedicated game server they should connect to.
* Dedicated game servers receive traffic as per normal from the Server Proxies, and send data back to the proxies
directly.
-* If the dedicated game server always expects traffic from only a single ip/port combination for client connection,
+* If the dedicated game server always expects traffic from only a single ip/port combination for client connection,
then traffic will always need to be sent through a single Server Proxy. Otherwise, UDP packets can be load
balanced via the Client Proxy to multiple Server Proxies for even greater redundancy.
## What Next?
-* Have a look at the [example configurations](./examples.md) for configuration and usage examples.
-* Review the [set of filters](./filters.md) that are available.
+* Have a look at the [Administration API](./admin.md).
+* Review the [set of filters](../services/proxy/filters.md) that are available.
---
Diagrams powered by asciiflow.com
-[client SDKs]: ./sdks.md
\ No newline at end of file
+[ue]: ../sdks/unreal-engine.md
diff --git a/docs/src/quickstarts/_agones.md b/docs/src/deployment/quickstarts/_agones.md
similarity index 100%
rename from docs/src/quickstarts/_agones.md
rename to docs/src/deployment/quickstarts/_agones.md
diff --git a/docs/src/quickstarts/agones-xonotic-sidecar.md b/docs/src/deployment/quickstarts/agones-xonotic-sidecar.md
similarity index 80%
rename from docs/src/quickstarts/agones-xonotic-sidecar.md
rename to docs/src/deployment/quickstarts/agones-xonotic-sidecar.md
index 55bf81a40f..7647079994 100644
--- a/docs/src/quickstarts/agones-xonotic-sidecar.md
+++ b/docs/src/deployment/quickstarts/agones-xonotic-sidecar.md
@@ -4,9 +4,9 @@
## 1. Agones Fleet with Quilkin
-In this step, we're going to set up a Xonotic dedicated game server, with Quilkin running as a
-[sidecar](../integrations.md#server-proxy-as-a-sidecar), which will give us access to all the
-[metrics](../proxy/metrics.md) that Quilkin provides.
+In this step, we're going to set up a Xonotic dedicated game server, with Quilkin running as a
+[sidecar](../examples.md#server-proxy-as-a-sidecar), which will give us access to all the
+[metrics](../../services/proxy/metrics.md) that Quilkin provides.
```shell
kubectl apply -f https://raw.githubusercontent.com/googleforgames/quilkin/{{GITHUB_REF_NAME}}/examples/agones-xonotic-sidecar/sidecar.yaml
@@ -16,7 +16,7 @@ This applies two resources to your cluster:
1. A Kubernetes [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) with a basic Quilkin
static configuration.
-2. An Agones [Fleet specification](https://agones.dev/site/docs/reference/fleet/) with Quilkin running as a sidecar
+2. An Agones [Fleet specification](https://agones.dev/site/docs/reference/fleet/) with Quilkin running as a sidecar
to Xonotic, such that it can process all the UDP traffic and pass it to the Xonotic dedicated game server.
Now you can run `kubectl get gameservers` until all your Agones `GameServers` are marked as `Ready` like so:
@@ -31,10 +31,10 @@ xonotic-sidecar-htc2x-sdp4k Ready 34.94.107.201 7599 gke-agones-default-
## 2. Play Xonotic!
Usually with Agones you would
-[Allocate](https://agones.dev/site/docs/getting-started/create-fleet/#4-allocate-a-game-server-from-the-fleet) a
+[Allocate](https://agones.dev/site/docs/getting-started/create-fleet/#4-allocate-a-game-server-from-the-fleet) a
`GameServer`, but we'll skip this step for this example.
-Choose one of the listed `GameServer`s from the previous step, and connect to the IP and port of the Xonotic
+Choose one of the listed `GameServer`s from the previous step, and connect to the IP and port of the Xonotic
server via the "Multiplayer > Address" field in the Xonotic client in the format of {IP}:{PORT}.
![xonotic-address.png](xonotic-address.png)
@@ -45,14 +45,14 @@ You should now be playing a game of Xonotic against 4 bots!
Let's take a look at some metrics that Quilkin outputs.
-Grab the name of the GameServer you connected to before, and replace the `${gameserver}` value below, and run the
+Grab the name of the GameServer you connected to before, and replace the `${gameserver}` value below, and run the
command. This will forward the [admin](../admin.md) interface to localhost.
```shell
kubectl port-forward ${gameserver} 9091
```
-Then open a browser to [http://localhost:9091/metrics](http://localhost:9091/metrics) to see the
+Then open a browser to [http://localhost:9091/metrics](http://localhost:9091/metrics) to see the
[Prometheus](https://prometheus.io/) metrics that Quilkin exports.
## 5. Cleanup
@@ -65,10 +65,10 @@ kubectl delete -f https://raw.githubusercontent.com/googleforgames/quilkin/{{GI
## 6. Agones Fleet, but with Compression
-Let's take this one step further and compress the data between the Xonotic client and the server, without having to
+Let's take this one step further and compress the data between the Xonotic client and the server, without having to
change either of them!
-Let's create a new Xonotic Fleet on our Agones cluster, but this time configured such that Quilkin will decompress
+Let's create a new Xonotic Fleet on our Agones cluster, but this time configured such that Quilkin will decompress
packets that are incoming.
Run the following:
@@ -77,7 +77,7 @@ Run the following:
kubectl apply -f https://raw.githubusercontent.com/googleforgames/quilkin/{{GITHUB_REF_NAME}}/examples/agones-xonotic-sidecar/sidecar-compress.yaml
```
-This will implement the [Compress](../proxy/filters/compress.md) filter in our Quilkin sidecar proxy in our new
+This will implement the [Compress](../../services/proxy/filters/compress.md) filter in our Quilkin sidecar proxy in our new
Fleet.
Now you can run `kubectl get gameservers` until all your Agones `GameServers` are marked as `Ready` like so:
@@ -91,30 +91,30 @@ xonotic-sidecar-compress-htc2x-sdp4k Ready 34.94.107.201 7592 gke-agones
## 4. Play Xonotic, through Quilkin
-What we will do in this step, is run Quilkin locally as a client-side proxy to compress the UDP data before it is
+What we will do in this step, is run Quilkin locally as a client-side proxy to compress the UDP data before it is
sent up to our Xonotic servers that are expecting compressed data.
-First, grab a copy of the Quilkin configuration
+First, grab a copy of the Quilkin configuration
client-compress.yaml
locally. This has the Compress filter already configured, but we need to fill in the address to connect to.
-> Rather than editing a file, this could also be sent through the [xDS API](../xds.md), but it is easier to
+> Rather than editing a file, this could also be sent through the [xDS API](../../services/xds.md), but it is easier to
> demonstrate this functionality through a static configuration.
-Instead of connecting Xonotic directly, take the IP and port from one of the Agones hosted `GameServer` records, and
-replace the `${GAMESERVER_IP}` and `${GAMESERVER_PORT}` values in your copy of `client-compress.yaml`.
+Instead of connecting Xonotic directly, take the IP and port from one of the Agones hosted `GameServer` records, and
+replace the `${GAMESERVER_IP}` and `${GAMESERVER_PORT}` values in your copy of `client-compress.yaml`.
Run this configuration locally as:
```shell
-quilkin -c ./client-compress.yaml run
+quilkin -c ./client-compress.yaml proxy
```
-Now we can connect to the local client proxy on "127.0.0.1:7000" via the "Multiplayer > Address" field in the
+Now we can connect to the local client proxy on "127.0.0.1:7777" via the "Multiplayer > Address" field in the
Xonotic client, and Quilkin will take care of compressing the data for you without having to change the game
client!
-Congratulations! You are now using Quilkin to manipulate the game client to server connection, without having to
+Congratulations! You are now using Quilkin to manipulate the game client to server connection, without having to
edit either!
## 7. Cleanup
@@ -128,4 +128,3 @@ kubectl delete -f https://raw.githubusercontent.com/googleforgames/quilkin/{{GIT
## What's Next?
* Have a look at the [examples](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples) folder for configuration and usage examples.
-* Explore the [usage documentation](../using.md) for other configuration options.
diff --git a/docs/src/quickstarts/agones-xonotic-xds.md b/docs/src/deployment/quickstarts/agones-xonotic-xds.md
similarity index 92%
rename from docs/src/quickstarts/agones-xonotic-xds.md
rename to docs/src/deployment/quickstarts/agones-xonotic-xds.md
index 85fcf2698e..7db19d26f7 100644
--- a/docs/src/quickstarts/agones-xonotic-xds.md
+++ b/docs/src/deployment/quickstarts/agones-xonotic-xds.md
@@ -9,8 +9,8 @@ In this quickstart, we'll be setting up an example [Xonotic](https://xonotic.org
Fleet, that will only be accessible through Quilkin, via utilising the [TokenRouter]
Filter to provide routing and access control to the Allocated `GameServer` instances.
-To do this, we'll take advantage of the Quilkin [Agones xDS Provider](../xds/providers/agones.md) to provide
-an out-of-the-box control plane for integration between Agones and [Quilkin's xDS configuration API](../xds.md) with
+To do this, we'll take advantage of the Quilkin [Agones xDS Provider](../../services/xds/providers/agones.md) to provide
+an out-of-the-box control plane for integration between Agones and [Quilkin's xDS configuration API](../../services/xds.md) with
minimal effort.
## 2. Install Quilkin Agones xDS Provider
@@ -79,22 +79,22 @@ quilkin-proxies-78965c446d-m4rr7 1/1 Running 0 6s
Let's take this one step further, and check the configuration of the proxies that should have come from the `quilkin
manage agones` instance.
-In another terminal, run: `kubectl port-forward deployments/quilkin-proxies 9091`, to port forward the
+In another terminal, run: `kubectl port-forward deployments/quilkin-proxies 8000`, to port forward the
[admin endpoint](../admin.md) locally, which we can then query.
-Go back to your original terminal and run `curl -s http://localhost:9091/config`
+Go back to your original terminal and run `curl -s http://localhost:8000/config`
-> If you have [jq](https://stedolan.github.io/jq/) installed, run `curl -s http://localhost:9091/config | jq` for a
+> If you have [jq](https://stedolan.github.io/jq/) installed, run `curl -s http://localhost:8000/config | jq` for a
> nicely formatted JSON output.
```shell
-$ curl -s http://localhost:9091/config
-{"admin":{"address":"0.0.0.0:9091"},"clusters":{},"filters":[{"name":"quilkin.filters.capture.v1alpha1.Capture","config":{"metadataKey":"quilkin.dev/capture","suffix":{"size":3,"remove":true}}},{"name":"quilkin.filters.token_router.v1alpha1.TokenRouter","config":null}],"id":"quilkin-proxies-78965c446d-dqvjg","management_servers":[{"address":"http://quilkin-manage-agones:80"}],"port":7000,"version":"v1alpha1","maxmind_db":null}%
+$ curl -s http://localhost:8000/config
+{"admin":{"address":"0.0.0.0:8000"},"clusters":{},"filters":[{"name":"quilkin.filters.capture.v1alpha1.Capture","config":{"metadataKey":"quilkin.dev/capture","suffix":{"size":3,"remove":true}}},{"name":"quilkin.filters.token_router.v1alpha1.TokenRouter","config":null}],"id":"quilkin-proxies-78965c446d-dqvjg","management_servers":[{"address":"http://quilkin-manage-agones:80"}],"port":7000,"version":"v1alpha1","maxmind_db":null}%
```
This shows us the current configuration of the proxies coming from the xDS server created via `quilkin manage
agones`. The most interesting part that we see here, is that we have a matching set of
-[Filters](../proxy/concepts.md#proxy-filters) that are found in the `ConfigMap` in the
+[Filters](../../services/proxy/filters.md) that are found in the `ConfigMap` in the
[xds-control-plane.yaml](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples/agones-xonotic-xds/xds-control-plane.yaml)
we installed earlier.
@@ -169,11 +169,11 @@ our authentication and routing token ("NDU2").
> You should use something more cryptographically random than `456` in your application.
-Let's run `curl -s http://localhost:9091/config` again, so we can see what has changed!
+Let's run `curl -s http://localhost:8000/config` again, so we can see what has changed!
```shell
-$ curl -s http://localhost:9091/config
-{"admin":{"address":"0.0.0.0:9091"},"clusters":{"default":{"localities":[{"locality":null,"endpoints":[{"address":"34.168.170.51:7226","metadata":{"quilkin.dev":{"tokens":["NDU2"]}}}]}]}},"filters":[{"name":"quilkin.filters.capture.v1alpha1.Capture","config":{"metadataKey":"quilkin.dev/capture","suffix":{"size":3,"remove":true}}},{"name":"quilkin.filters.token_router.v1alpha1.TokenRouter","config":null}],"id":"quilkin-proxies-78965c446d-tfgsj","management_servers":[{"address":"http://quilkin-manage-agones:80"}],"port":7000,"version":"v1alpha1","maxmind_db":null}%
+$ curl -s http://localhost:8000/config
+{"admin":{"address":"0.0.0.0:8000"},"clusters":{"default":{"localities":[{"locality":null,"endpoints":[{"address":"34.168.170.51:7226","metadata":{"quilkin.dev":{"tokens":["NDU2"]}}}]}]}},"filters":[{"name":"quilkin.filters.capture.v1alpha1.Capture","config":{"metadataKey":"quilkin.dev/capture","suffix":{"size":3,"remove":true}}},{"name":"quilkin.filters.token_router.v1alpha1.TokenRouter","config":null}],"id":"quilkin-proxies-78965c446d-tfgsj","management_servers":[{"address":"http://quilkin-manage-agones:80"}],"port":7000,"version":"v1alpha1","maxmind_db":null}%
```
Looking under `clusters` > `localities` > `endpoints` we can see an address and token that matches up with the
@@ -199,7 +199,7 @@ quilkin-proxies LoadBalancer 10.109.0.12 35.246.94.14 7000:30174/UDP
We have a [Quilkin config yaml](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples/agones-xonotic-xds/client-token.yaml)
file all ready for you, that is configured to append the routing token `456` to each
packet that passes through it, via the power of a
-[ConcatenateBytes](../proxy/filters/concatenate_bytes.md) Filter.
+[ConcatenateBytes](../../services/proxy/filters/concatenate_bytes.md) Filter.
Download `client-token.yaml` locally, so you can edit it:
@@ -230,9 +230,9 @@ proxies will route to the Allocated GameServer, and you can play a gamee!
## What's Next?
-* Check out the variety of [Filters](../filters.md) that are possible with Quilkin.
-* Read into the [xDS Managment API](../xds.md).
+* Check out the variety of [Filters](../../services/proxy/filters.md) that are possible with Quilkin.
+* Read into the [xDS Managment API](../../services/xds.md).
[ConfigMap]: https://kubernetes.io/docs/concepts/configuration/configmap/
-[Capture]: ../proxy/filters/capture.md
-[TokenRouter]: ../proxy/filters/token_router.md
\ No newline at end of file
+[Capture]: ../../services/proxy/filters/capture.md
+[TokenRouter]: ../../services/proxy/filters/token_router.md
diff --git a/docs/src/quickstarts/netcat.md b/docs/src/deployment/quickstarts/netcat.md
similarity index 61%
rename from docs/src/quickstarts/netcat.md
rename to docs/src/deployment/quickstarts/netcat.md
index 08a30da1b7..70a5b747f6 100644
--- a/docs/src/quickstarts/netcat.md
+++ b/docs/src/deployment/quickstarts/netcat.md
@@ -14,7 +14,7 @@ So that we have a target for sending UDP packets to, let's use `ncat` to create
To do this run:
```shell
-ncat -e $(which cat) -k -u -l 8000
+ncat -e $(which cat) -k -u -l 8080
```
This routes all UDP packets that `ncat` receives to the local `cat` process, which echoes it back.
@@ -25,18 +25,22 @@ Next let's configure Quilkin in proxy mode, with a static configuration that poi
UDP echo service we just started.
```shell
-quilkin proxy --to 127.0.0.1:8000
+quilkin proxy --to 127.0.0.1:8080
```
-This configuration will start Quilkin on the default port of 7000, and it will
-redirect all incoming UDP traffic to a single endpoint of 127.0.0.1, port 8000.
+This configuration will start Quilkin on the [default proxy port](../../services/proxy.md), and it will
+redirect all incoming UDP traffic to a single endpoint of 127.0.0.1, port 8080.
You should see an output like the following:
```shell
-{"msg":"Starting Quilkin","level":"INFO","ts":"2021-04-25T19:27:22.535174615-07:00","source":"run","version":"0.1.0-dev"}
-{"msg":"Starting","level":"INFO","ts":"2021-04-25T19:27:22.535315827-07:00","source":"server::Server","port":7000}
-{"msg":"Starting admin endpoint","level":"INFO","ts":"2021-04-25T19:27:22.535550572-07:00","source":"proxy::Admin","address":"[::]:9091"}
+{"timestamp":"2023-01-19T10:16:23.399277Z","level":"INFO","fields":{"message":"Starting Quilkin","version":"0.6
+.0-dev","commit":"72176a191ffc3a597e3834ee1d0090b30caf81d4"},"target":"quilkin::cli","filename":"src/cli.rs"}
+{"timestamp":"2023-01-19T10:16:23.399771Z","level":"INFO","fields":{"message":"Starting admin endpoint","addres
+s":"0.0.0.0:8000"},"target":"quilkin::admin","filename":"src/admin.rs"}
+{"timestamp":"2023-01-19T10:16:23.400544Z","level":"INFO","fields":{"message":"Starting","port":7777,"proxy_id"
+:"7e9fc464-6ccc-41fe-afc4-6c97089de9b8"},"target":"quilkin::proxy","filename":"src/proxy.rs"}
+{"timestamp":"2023-01-19T10:16:23.401192Z","level":"INFO","fields":{"message":"Quilkin is ready"},"target":"qui
```
## 3. Send a packet!
@@ -46,13 +50,13 @@ In (yet 😃) another shell, let's use netcat to send an udp packet.
Run the following to connect netcat to Quilkin's receiving port of 7000 via UDP (`-u`):
```shell
-nc -u 127.0.0.1 7000
+nc -u 127.0.0.1 7777
```
Type the word "test" and hit enter, you should see it echoed back to you like so:
```shell
-nc -u 127.0.0.1 7000
+nc -u 127.0.0.1 7777
test
test
```
@@ -65,4 +69,3 @@ What's next?
* Run through the [Quilkin with Agones quickstart](agones-xonotic-sidecar.md).
* Have a look at some of [the examples](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples) we have.
-* Check out the [usage documentation](../using.md) for other configuration options.
diff --git a/docs/src/quickstarts/xonotic-address.png b/docs/src/deployment/quickstarts/xonotic-address.png
similarity index 100%
rename from docs/src/quickstarts/xonotic-address.png
rename to docs/src/deployment/quickstarts/xonotic-address.png
diff --git a/docs/src/examples.md b/docs/src/examples.md
deleted file mode 100644
index 72cc9b539e..0000000000
--- a/docs/src/examples.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Examples
-
-See the [examples](https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/examples) folder on Github for configuration and
-usage examples.
-
-> Depending on which release version of Quilkin you are using, you may need to choose the appropriate release tag
-> from the dropdown, as the API surface for Quilkin is still under development.
-
-Examples include:
-* Quilkin running as a sidecar while hosted on [Agones].
-* Quilkin running as an [xDS](./xds.md) [Agones] provider for Quilkin proxies.
-* [iperf3](https://iperf.fr/) throughput.
-* [Grafana](https://grafana.com/) dashboards.
-
-...and more!
-
-[Agones]: https://agones.dev/
diff --git a/docs/src/faq.md b/docs/src/faq.md
index 0d26401475..afff279504 100644
--- a/docs/src/faq.md
+++ b/docs/src/faq.md
@@ -37,14 +37,14 @@ separate binary is not an option.
This is an ongoing discussion, and since console development is protected by non-disclosure agreements, we can't
comment on this directly.
-That being said, we have started implementing lean [Client SDK](./sdks.md) versions of certain filters that work
-with known supported game engines and languages for circumstances where compiling Rust or providing a separate
-Quilkin binary as an executable is not an option.
+That being said, we have an [Unreal Engine](./sdks/unreal-engine.md) for games
+in circumstances where compiling Rust or providing a separate Quilkin binary as
+an executable is not an option.
## Any reason you didn't contribute this into/extend Envoy?
This is an excellent question! [Envoy](https://www.envoyproxy.io/) is an amazing project, and has set many of the
-standards for how [proxies are written and orchestrated](./xds.md), and was an inspiration for many of
+standards for how [proxies are written and orchestrated](./services/xds.md), and was an inspiration for many of
the decisions made on Quilkin.
However, we decided to build this project separately:
diff --git a/docs/src/installation.md b/docs/src/installation.md
new file mode 100644
index 0000000000..5ca4695865
--- /dev/null
+++ b/docs/src/installation.md
@@ -0,0 +1,51 @@
+# Installation
+
+There are variety of automated and manual methods for installing Quilkin onto
+your system. For cloud deployments Quilkin provides a [container image](#oci-image)
+to make it easily to immediately start using it. You can also install Quilkin on
+your local machine through [Cargo](#cargo).
+
+## Distributions
+
+### [OCI Image](https://us-docker.pkg.dev/quilkin/release/quilkin)
+
+
+ - Source / Method
+ -
+
+```
+us-docker.pkg.dev/quilkin/release/quilkin:{{QUILKIN_VERSION}}
+```
+
+
+ - Notes
+ - Pre-built Quilkin binary with no preset arguments
+
+
+### [Cargo](https://lib.rs/crates/quilkin)
+
+
+ - Source / Method
+ -
+
+```
+cargo install quilkin
+```
+
+
+ - Notes
+ - Compiled from source using cargo
+
+
+### [GitHub](https://github.com/googleforgames/quilkin)
+
+
+ - Source / Method
+ -
+
+[GitHub Releases](https://github.com/googleforgames/quilkin/releases)
+
+
+ - Notes
+ - Pre-built binaries for manual installation
+
diff --git a/docs/src/introduction.md b/docs/src/introduction.md
index ee64d642fe..587d8ae7c3 100644
--- a/docs/src/introduction.md
+++ b/docs/src/introduction.md
@@ -40,6 +40,22 @@ Quilkin incorporates these abilities:
## What Next?
-* Read the [usage guide](./using.md)
-* Have a look at the [example configurations](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples) for basic configuration examples.
-* Check out the [example integration patterns](./integrations.md).
+Quilkin provides a variety of different services depending on your use-case.
+The primary service is [`proxy`](./services/proxy.md), which runs a reverse UDP
+proxy. To see a basic usage of the command-line interface run through the
+[netcat with Quilkin quickstart](./deployment/quickstarts/netcat.md).
+
+For more advanced usage, you might also be interested in:
+
+* Checking out the [installation guide](./installation.md)
+* Having a look at the [example projects](https://github.com/googleforgames/quilkin/blob/{{GITHUB_REF_NAME}}/examples) for basic configuration examples.
+* Checking out the [example deployment architecture](./deployment/examples.md)
+ for deploying quilkin for your game network.
+
+
+```shell
+$ quilkin --help
+{{#include ../../target/quilkin.commands}}
+```
+
+[log-docs]: https://docs.rs/env_logger/0.9.0/env_logger/#enabling-logging
diff --git a/docs/src/proxy-mode.md b/docs/src/proxy-mode.md
deleted file mode 100644
index 242b1c3108..0000000000
--- a/docs/src/proxy-mode.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Proxy Mode
-
-The "proxy mode" is the primary mode of operation for Quilkin, wherein it acts as a non-transparent UDP proxy.
-
-This is driven by Quilkin being [executed](./using.md#command-line-interface) via the
-[`proxy` subcommand](../api/quilkin/cli/struct.Proxy.html).
-
-To view all the options for the `proxy` subcommand, run:
-
-```shell
-$ quilkin proxy --help
-{{#include ../../target/quilkin.proxy.commands}}
-```
diff --git a/docs/src/proxy/maxmind.md b/docs/src/proxy/maxmind.md
deleted file mode 100644
index 402c130f6b..0000000000
--- a/docs/src/proxy/maxmind.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# ASN Maxmind Information
-
-If Quilkin is provided a
-remote URL or local file path to a
-Maxmind IP Geolocation database through the `mmdb` [file](../file-configuration.md) or
-[command line](../../api/quilkin/cli/struct.Proxy.html#structfield.mmdb)
-configuration, Quilkin will log the following information in the `maxmind information` log.
-
-| Field | Description |
-|-----------------|-----------------------------------------------|
-| `number` | ASN Number |
-| `organization` | The organisation responsible for the ASN |
-| `country_code` | The corresponding country code |
-| `prefix` | The IP prefix CIDR address |
-| `prefix_entity` | The name of the entity for the prefix address |
-| `prefix_name` | The name of the prefix address |
-
-> Maxmind databases often require a licence and/or fee, so they aren't included
-> by default with Quilkin.
diff --git a/docs/src/quickstart.md b/docs/src/quickstart.md
deleted file mode 100644
index a5b53a7b01..0000000000
--- a/docs/src/quickstart.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Quickstart
-
-This section provides a series of quickstarts to get you up and running with Quilkin quickly!
\ No newline at end of file
diff --git a/docs/src/sdks.md b/docs/src/sdks.md
deleted file mode 100644
index 0a0e61ac78..0000000000
--- a/docs/src/sdks.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# SDKs
-
-You will learn here about Quilkin's lightweight integration SDKs that can be used as clients for interacting
-with your hosted Quilkin UDP proxies, for situations where it is not possible to run or integrate Quilkin in your
-game client.
-
diff --git a/docs/src/proxy/concepts.md b/docs/src/services/proxy.md
similarity index 82%
rename from docs/src/proxy/concepts.md
rename to docs/src/services/proxy.md
index 86cc92b12f..d9c26fd630 100644
--- a/docs/src/proxy/concepts.md
+++ b/docs/src/services/proxy.md
@@ -1,23 +1,32 @@
-# Proxy Concepts
+# Proxy
-The Concepts section helps you learn about the parts of Quilkin when running as proxy and how they work toghether.
+| services | ports | Protocol |
+|----------|-------|-----------|
+| proxy | 7777 | UDP (IPv4) |
-## Local Port
+"Proxy" is the primary Quilkin service, which acts as a non-transparent UDP
+proxy.
-This is the `port` configuration, in which initial connections to Quilkin are made. Defaults to `7000`.
+To view all the options for the `proxy` subcommand, run:
+
+```shell
+$ quilkin proxy --help
+{{#include ../../../target/quilkin.proxy.commands}}
+```
## Endpoints
An Endpoint represents an address that Quilkin forwards packets to that it has recieved from the
-[Local Port](#local-port), and recieves data from as well.
+source port.
It is represented by an IP address and port. An Endpoint can optionally be associated with an arbitrary set of
[metadata](#endpoint-metadata) as well.
## Proxy Filters
-Filters are the way for a Quilkin proxy to intercept UDP traffic travelling between a [Local Port] and
-[Endpoints][Endpoint] in either direction, and be able to inpsect, manipulate, and route the packets as desired.
+Filters are the way for a Quilkin proxy to intercept UDP packet traffic from the
+source and [Endpoints][Endpoint] in either direction, and be able to inpsect,
+manipulate, and route the packets as desired.
See [Filters][filters-doc] for a deeper dive into Filters, as well as the list of build in Filters that come with
Quilkin.
@@ -77,11 +86,8 @@ Sessions are established *after* the filter chain completes. The destination End
the [filter chain][filter-doc], so a Session can only be created after filter chain completion. For example, if the
filter chain drops all packets, then no session will ever be created.
-[Local Port]: #local-port
-[sessions-doc]: ./session.md
-[filters-doc]: ../filters.md
[Endpoint]: #endpoints
-[file-configuration]: ../file-configuration.md
+[file-configuration]: ../deployment/configuration.md
[xds-endpoint-metadata]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/endpoint/v3/endpoint_components.proto#envoy-v3-api-field-config-endpoint-v3-lbendpoint-metadata
-[dynamic-configuration-doc]: ../xds.md
-[TokenRouter]: filters/token_router.md
+[dynamic-configuration-doc]: ./xds.md
+[TokenRouter]: ./proxy/filters/token_router.md
diff --git a/docs/src/filters.md b/docs/src/services/proxy/filters.md
similarity index 80%
rename from docs/src/filters.md
rename to docs/src/services/proxy/filters.md
index 8f8a07375d..c2f8e06c4b 100644
--- a/docs/src/filters.md
+++ b/docs/src/services/proxy/filters.md
@@ -1,4 +1,4 @@
-# Proxy Filters
+# Packet Filters
In most cases, we would like Quilkin to do some preprocessing of received packets before sending them off to their destination. Because this stage is entirely specific to the use case at hand and differs between Quilkin deployments, we must have a say over what tweaks to perform - this is where filters come in.
@@ -14,7 +14,7 @@ As an example, say we would like to perform the following steps in our processin
* Do not forward (drop) the packet if its compressed length is over 512 bytes.
We would create a filter corresponding to each step either by leveraging any [existing filters](#built-in-filters)
-that do what we want or [writing one ourselves](proxy/filters/writing_custom_filters.md) and connect them to form the
+that do what we want or [writing one ourselves](./filters/writing_custom_filters.md) and connect them to form the
following filter chain:
```bash
@@ -49,7 +49,7 @@ filters:
config:
max_packets: 10
period: 1
-clusters:
+clusters:
default:
localities:
- endpoints:
@@ -94,16 +94,16 @@ Quilkin includes several filters out of the box.
| Filter | Description |
|----------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| [Capture] | Capture specific bytes from a packet and store them in [filter dynamic metadata](#filter-dynamic-metadata). |
-| [Compress](proxy/filters/compress.md) | Compress and decompress packets data. |
-| [ConcatenateBytes](proxy/filters/concatenate_bytes.md) | Add authentication tokens to packets. |
-| [Debug] | Logs every packet. |
-| [Drop](proxy/filters/drop.md) | Drop all packets |
-| [Firewall](proxy/filters/firewall.md) | Allowing/blocking traffic by IP and port. |
-| [LoadBalancer](proxy/filters/load_balancer.md) | Distributes downstream packets among upstream endpoints. |
+| [Compress](./filters/compress.md) | Compress and decompress packets data. |
+| [ConcatenateBytes](./filters/concatenate_bytes.md) | Add authentication tokens to packets. |
+| [Debug](./filters/concatenate_bytes.md) | Logs every packet. |
+| [Drop](./filters/drop.md) | Drop all packets |
+| [Firewall](./filters/firewall.md) | Allowing/blocking traffic by IP and port. |
+| [LoadBalancer](./filters/load_balancer.md) | Distributes downstream packets among upstream endpoints. |
| [LocalRateLimit] | Limit the frequency of packets. |
-| [Match](proxy/filters/match.md) | Change Filter behaviour based on dynamic metadata |
-| [Pass](proxy/filters/pass.md) | Allow all packets through |
-| [Timestamp](proxy/filters/timestamp.md) | Accepts a UNIX timestamp from metadata and observes the duration between that timestamp and now. |
+| [Match](./filters/match.md) | Change Filter behaviour based on dynamic metadata |
+| [Pass](./filters/pass.md) | Allow all packets through |
+| [Timestamp](./filters/timestamp.md) | Accepts a UNIX timestamp from metadata and observes the duration between that timestamp and now. |
| [TokenRouter] | Send packets to endpoints based on metadata. |
## FilterConfig
@@ -127,8 +127,8 @@ properties:
required: [ 'name' ]
```
-[Capture]: proxy/filters/capture.md
-[TokenRouter]: proxy/filters/token_router.md
-[Debug]: proxy/filters/debug.md
-[LocalRateLimit]: proxy/filters/local_rate_limit.md
-[`quilkin::metadata::Value`]: ../api/quilkin/metadata/enum.Value.html
+[Capture]: ./filters/capture.md
+[TokenRouter]: ./filters/token_router.md
+[Debug]: ./filters/debug.md
+[LocalRateLimit]: ./filters/local_rate_limit.md
+[`quilkin::metadata::Value`]: ../../../api/quilkin/metadata/enum.Value.html
diff --git a/docs/src/proxy/filters/capture.md b/docs/src/services/proxy/filters/capture.md
similarity index 81%
rename from docs/src/proxy/filters/capture.md
rename to docs/src/services/proxy/filters/capture.md
index 874ac0555d..89aff82ff9 100644
--- a/docs/src/proxy/filters/capture.md
+++ b/docs/src/services/proxy/filters/capture.md
@@ -1,6 +1,6 @@
-# CaptureBytes
+# Capture
-The `CaptureBytes` filter's job is to find a series of bytes within a packet, and capture it into
+The `Capture` filter's job is to find a series of bytes within a packet, and capture it into
[Filter Dynamic Metadata][filter-dynamic-metadata], so that it can be utilised by filters further
down the chain.
@@ -51,10 +51,10 @@ clusters:
# quilkin::Proxy::try_from(config).unwrap();
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/capture/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/capture/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.capture.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.capture.v1alpha1.yaml}}
```
## Metrics
@@ -63,4 +63,4 @@ clusters:
A counter of the total number of packets that have been dropped due to their length being less than the configured
`size`.
-[filter-dynamic-metadata]: ../../filters.md#filter-dynamic-metadata
+[filter-dynamic-metadata]: ../filters.md#filter-dynamic-metadata
diff --git a/docs/src/proxy/filters/compress.md b/docs/src/services/proxy/filters/compress.md
similarity index 91%
rename from docs/src/proxy/filters/compress.md
rename to docs/src/services/proxy/filters/compress.md
index d3ca5bef10..ac9f46f75e 100644
--- a/docs/src/proxy/filters/compress.md
+++ b/docs/src/services/proxy/filters/compress.md
@@ -18,7 +18,7 @@ filters:
on_read: COMPRESS
on_write: DECOMPRESS
mode: SNAPPY
-clusters:
+clusters:
default:
localities:
- endpoints:
@@ -34,13 +34,13 @@ sent to the local listening port and then compressed when heading up to a dedica
decompressed when traffic is returned from the dedicated game server before being handed back to game client.
> It is worth noting that since the Compress filter modifies the *entire packet*, it is worth paying special
- attention to the order it is placed in your [Filter configuration](../../filters.md). Most of the time it will likely be
+ attention to the order it is placed in your [Filter configuration](../filters.md). Most of the time it will likely be
the first or last Filter configured to ensure it is compressing the entire set of data being sent.
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/compress/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/compress/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.compress.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.compress.v1alpha1.yaml}}
```
## Compression Modes
diff --git a/docs/src/proxy/filters/concatenate_bytes.md b/docs/src/services/proxy/filters/concatenate_bytes.md
similarity index 82%
rename from docs/src/proxy/filters/concatenate_bytes.md
rename to docs/src/services/proxy/filters/concatenate_bytes.md
index bc62eb3d31..c34650b366 100644
--- a/docs/src/proxy/filters/concatenate_bytes.md
+++ b/docs/src/services/proxy/filters/concatenate_bytes.md
@@ -29,10 +29,10 @@ clusters:
# quilkin::Proxy::try_from(config).unwrap();
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/concatenate_bytes/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/concatenate_bytes/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.concatenate_bytes.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.concatenate_bytes.v1alpha1.yaml}}
```
## Metrics
diff --git a/docs/src/proxy/filters/debug.md b/docs/src/services/proxy/filters/debug.md
similarity index 83%
rename from docs/src/proxy/filters/debug.md
rename to docs/src/services/proxy/filters/debug.md
index 05385a11c6..3f85fa6e05 100644
--- a/docs/src/proxy/filters/debug.md
+++ b/docs/src/services/proxy/filters/debug.md
@@ -28,10 +28,10 @@ clusters:
# quilkin::Proxy::try_from(config).unwrap();
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/debug/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/debug/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.debug.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.debug.v1alpha1.yaml}}
```
diff --git a/docs/src/proxy/filters/drop.md b/docs/src/services/proxy/filters/drop.md
similarity index 100%
rename from docs/src/proxy/filters/drop.md
rename to docs/src/services/proxy/filters/drop.md
diff --git a/docs/src/proxy/filters/firewall.md b/docs/src/services/proxy/filters/firewall.md
similarity index 91%
rename from docs/src/proxy/filters/firewall.md
rename to docs/src/services/proxy/filters/firewall.md
index c5d7736e39..4937387352 100644
--- a/docs/src/proxy/filters/firewall.md
+++ b/docs/src/services/proxy/filters/firewall.md
@@ -37,10 +37,10 @@ clusters:
# quilkin::Proxy::try_from(config).unwrap();
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/firewall/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/firewall/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.firewall.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.firewall.v1alpha1.yaml}}
```
### Rule Evaluation
diff --git a/docs/src/proxy/filters/load_balancer.md b/docs/src/services/proxy/filters/load_balancer.md
similarity index 84%
rename from docs/src/proxy/filters/load_balancer.md
rename to docs/src/services/proxy/filters/load_balancer.md
index 551482d26a..a19d319cb9 100644
--- a/docs/src/proxy/filters/load_balancer.md
+++ b/docs/src/services/proxy/filters/load_balancer.md
@@ -32,10 +32,10 @@ clusters:
The load balancing policy (the strategy to use to select what endpoint to send traffic to) is configurable.
In the example above, packets will be distributed by selecting endpoints in turn, in round robin fashion.
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/load_balancer/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/load_balancer/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.load_balancer.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.load_balancer.v1alpha1.yaml}}
```
## Metrics
diff --git a/docs/src/proxy/filters/local_rate_limit.md b/docs/src/services/proxy/filters/local_rate_limit.md
similarity index 85%
rename from docs/src/proxy/filters/local_rate_limit.md
rename to docs/src/services/proxy/filters/local_rate_limit.md
index 9b109c40f5..3f175316c5 100644
--- a/docs/src/proxy/filters/local_rate_limit.md
+++ b/docs/src/services/proxy/filters/local_rate_limit.md
@@ -1,6 +1,6 @@
# LocalRateLimit
-The LocalRateLimit filter controls the frequency at which packets received downstream are forwarded upstream by the proxy.
+The LocalRateLimit filter controls the frequency at which packets received downstream are forwarded upstream by the proxy.
Rate limiting is done independently per source (IP, Port) combination.
## Filter name
@@ -21,7 +21,7 @@ filters:
config:
max_packets: 1000
period: 1
-clusters:
+clusters:
default:
localities:
- endpoints:
@@ -41,14 +41,14 @@ To configure a rate limiter, we specify the maximum rate at which the proxy is a
> Packets that that exceeds the maximum configured rate are dropped.
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/local_rate_limit/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/local_rate_limit/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.local_rate_limit.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.local_rate_limit.v1alpha1.yaml}}
```
## Metrics
-* `quilkin_filter_LocalRateLimit_packets_dropped_total`
+* `quilkin_filter_LocalRateLimit_packets_dropped_total`
A counter over the total number of packets that have exceeded the configured maximum rate limit and have been dropped as a result.
diff --git a/docs/src/proxy/filters/match.md b/docs/src/services/proxy/filters/match.md
similarity index 83%
rename from docs/src/proxy/filters/match.md
rename to docs/src/services/proxy/filters/match.md
index 1823d1e38d..7fb8d43534 100644
--- a/docs/src/proxy/filters/match.md
+++ b/docs/src/services/proxy/filters/match.md
@@ -43,13 +43,13 @@ filters:
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/match/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/match/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.match.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.match.v1alpha1.yaml}}
```
-View the [Match](../../../api/quilkin/filters/match/struct.Config.html) filter documentation for more details.
+View the [Match](../../../../api/quilkin/filters/match/struct.Config.html) filter documentation for more details.
## Metrics
diff --git a/docs/src/proxy/filters/pass.md b/docs/src/services/proxy/filters/pass.md
similarity index 100%
rename from docs/src/proxy/filters/pass.md
rename to docs/src/services/proxy/filters/pass.md
diff --git a/docs/src/proxy/filters/timestamp.md b/docs/src/services/proxy/filters/timestamp.md
similarity index 85%
rename from docs/src/proxy/filters/timestamp.md
rename to docs/src/services/proxy/filters/timestamp.md
index ed5e9788ac..5de4581e3d 100644
--- a/docs/src/proxy/filters/timestamp.md
+++ b/docs/src/services/proxy/filters/timestamp.md
@@ -33,10 +33,10 @@ clusters:
# quilkin::Proxy::try_from(config).unwrap();
```
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/timestamp/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/timestamp/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.timestamp.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.timestamp.v1alpha1.yaml}}
```
## Metrics
diff --git a/docs/src/proxy/filters/token_router.md b/docs/src/services/proxy/filters/token_router.md
similarity index 92%
rename from docs/src/proxy/filters/token_router.md
rename to docs/src/services/proxy/filters/token_router.md
index b16948f16f..42562480d4 100644
--- a/docs/src/proxy/filters/token_router.md
+++ b/docs/src/services/proxy/filters/token_router.md
@@ -42,10 +42,10 @@ clusters:
View the [CaptureBytes](capture.md) filter documentation for more details.
-## Configuration Options ([Rust Doc](../../../api/quilkin/filters/token_router/struct.Config.html))
+## Configuration Options ([Rust Doc](../../../../api/quilkin/filters/token_router/struct.Config.html))
```yaml
-{{#include ../../../../target/quilkin.filters.token_router.v1alpha1.yaml}}
+{{#include ../../../../../target/quilkin.filters.token_router.v1alpha1.yaml}}
```
## Metrics
@@ -108,5 +108,5 @@ clusters:
On the game client side the [ConcatenateBytes](concatenate_bytes.md) filter could also be used to add authentication
tokens to outgoing packets.
-[filter-dynamic-metadata]: ../../filters.md#filter-dynamic-metadata
-[endpoint-tokens]: ../concepts.md#endpoints
+[filter-dynamic-metadata]: ../filters.md#filter-dynamic-metadata
+[endpoint-tokens]: ../../proxy.md#endpoints
diff --git a/docs/src/proxy/filters/writing_custom_filters.md b/docs/src/services/proxy/filters/writing_custom_filters.md
similarity index 80%
rename from docs/src/proxy/filters/writing_custom_filters.md
rename to docs/src/services/proxy/filters/writing_custom_filters.md
index de329fa558..17f3059f51 100644
--- a/docs/src/proxy/filters/writing_custom_filters.md
+++ b/docs/src/services/proxy/filters/writing_custom_filters.md
@@ -91,7 +91,7 @@ Add a main function that starts the proxy.
```rust,no_run,noplayground,ignore
// src/main.rs
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:run}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:run}}
```
Now, let's try out the proxy. The following configuration starts our extended
@@ -153,14 +153,14 @@ serde_yaml = "0.8"
```rust,no_run,noplayground,ignore
// src/main.rs
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:serde_config}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:serde_config}}
```
3. Update the `Greet` Filter to take in `greeting` as a parameter:
```rust,no_run,noplayground,ignore
// src/main.rs
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:filter}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:filter}}
```
### Protobuf Configuration
@@ -184,7 +184,7 @@ prost-types = "0.7"
```plaintext,no_run,noplayground,ignore
// src/greet.proto
-{{#include ../../../../examples/quilkin-filter-example/src/greet.proto:proto}}
+{{#include ../../../../../examples/quilkin-filter-example/src/greet.proto:proto}}
```
3. Generate Rust code from the proto file:
@@ -205,7 +205,7 @@ prost-build = "0.7"
```rust,no_run,noplayground,ignore
// src/build.rs
-{{#include ../../../../examples/quilkin-filter-example/build.rs:build}}
+{{#include ../../../../../examples/quilkin-filter-example/build.rs:build}}
```
To include the generated code, we'll use [`tonic::include_proto`], then we just
@@ -215,9 +215,9 @@ equivalvent configuration.
```rust,no_run,noplayground,ignore
// src/main.rs
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:include_proto}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:include_proto}}
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:TryFrom}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:TryFrom}}
```
Now, let's update `Greet`'s `StaticFilter` implementation to use the two
@@ -225,7 +225,7 @@ configurations.
```rust,no_run,noplayground,ignore
// src/main.rs
-{{#include ../../../../examples/quilkin-filter-example/src/main.rs:factory}}
+{{#include ../../../../../examples/quilkin-filter-example/src/main.rs:factory}}
```
That's it! With these changes we have wired up static configuration for our
@@ -233,27 +233,27 @@ filter. Try it out with the following configuration:
```yaml
# quilkin.yaml
-{{#include ../../../../examples/quilkin-filter-example/config.yaml:yaml}}
+{{#include ../../../../../examples/quilkin-filter-example/config.yaml:yaml}}
```
-[FilterInstance]: ../../../api/quilkin/filters/prelude/struct.FilterInstance.html
-[Filter]: ../../../api/quilkin/filters/trait.Filter.html
-[FilterFactory]: ../../../api/quilkin/filters/trait.FilterFactory.html
-[filter-factory-name]: ../../../api/quilkin/filters/trait.FilterFactory.html#tymethod.name
-[FilterRegistry]: ../../../api/quilkin/filters/struct.FilterRegistry.html
-[FilterRegistry::register]: ../../../api/quilkin/filters/struct.FilterRegistry.html#method.register
+[FilterInstance]: ../../../../api/quilkin/filters/prelude/struct.FilterInstance.html
+[Filter]: ../../../../api/quilkin/filters/trait.Filter.html
+[FilterFactory]: ../../../../api/quilkin/filters/trait.FilterFactory.html
+[filter-factory-name]: ../../../../api/quilkin/filters/trait.FilterFactory.html#tymethod.name
+[FilterRegistry]: ../../../../api/quilkin/filters/struct.FilterRegistry.html
+[FilterRegistry::register]: ../../../../api/quilkin/filters/struct.FilterRegistry.html#method.register
[Proxy::try_from]: ../../../api/struct.Proxy.html#impl-TryFrom%3CConfig%3E
[CreateFilterArgs::config]: ../../../api/quilkin/filters/prelude/struct.CreateFilterArgs.html#structfield.config
-[ConfigType::dynamic]: ../../../api/quilkin/config/enum.ConfigType.html#variant.Dynamic
-[ConfigType::static]: ../../../api/quilkin/config/enum.ConfigType.html#variant.Static
-[ConfigType::deserialize]: ../../../api/quilkin/config/enum.ConfigType.html#method.deserialize
+[ConfigType::dynamic]: ../../../../api/quilkin/config/enum.ConfigType.html#variant.Dynamic
+[ConfigType::static]: ../../../../api/quilkin/config/enum.ConfigType.html#variant.Static
+[ConfigType::deserialize]: ../../../../api/quilkin/config/enum.ConfigType.html#method.deserialize
[std::convert::TryFrom]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
-[Filters]: ../../filters.md
-[filter chain]: ../../filters.md#filters-and-filter-chain
-[built-in-filters]: ../../filters.md#built-in-filters
-[filter configuration]: ../../filters.md#filter-config
-[proxy-config]: ../../file-configuration.md
+[Filters]: ../filters.md
+[filter chain]: ../filters.md#filters-and-filter-chain
+[built-in-filters]: ../filters.md#built-in-filters
+[filter configuration]: ../filters.md#filter-config
+[proxy-config]: ../../deployment/configuration.md
[management server]: ../../xds.md
[tokio]: https://docs.rs/tokio
[tonic]: https://docs.rs/tonic
diff --git a/docs/src/proxy/metrics.md b/docs/src/services/proxy/metrics.md
similarity index 71%
rename from docs/src/proxy/metrics.md
rename to docs/src/services/proxy/metrics.md
index 3168cdbea1..ad5fb3d489 100644
--- a/docs/src/proxy/metrics.md
+++ b/docs/src/services/proxy/metrics.md
@@ -2,6 +2,24 @@
The following are metrics that Quilkin provides while in Proxy Mode.
+# ASN Maxmind Information
+
+If Quilkin is provided a a MaxmindDB GeoIP database, Quilkin will log the
+following information in the `maxmind information` log, as well provide metrics
+that use the following fields as labels.
+
+| Field | Description |
+|-----------------|-----------------------------------------------|
+| `number` | ASN Number |
+| `organization` | The organisation responsible for the ASN |
+| `country_code` | The corresponding country code |
+| `prefix` | The IP prefix CIDR address |
+| `prefix_entity` | The name of the entity for the prefix address |
+| `prefix_name` | The name of the prefix address |
+
+> Maxmind databases often require a licence and/or fee, so they aren't included
+> by default with Quilkin.
+
## General Metrics
The proxy exposes the following general metrics:
@@ -26,7 +44,7 @@ The proxy exposes the following general metrics:
* `quilkin_cluster_active_endpoints`
- The number of currently active upstream endpoints. Note that this tracks the number of endpoints that the proxy
+ The number of currently active upstream endpoints. Note that this tracks the number of endpoints that the proxy
knows of rather than those that it is connected to (see [Session Metrics][session-metrics] instead for those)
* `quilkin_bytes_total{event}`
@@ -53,9 +71,9 @@ The proxy exposes the following metrics around sessions:
* `quilkin_session_active{asn}{ip_prefix}`
- The number of currently active sessions. If a [maxmind](maxmind.md) database has been provided, the labels are
- populated:
- * The `asn` label is the [ASN](https://en.wikipedia.org/wiki/Autonomous_system_(Internet)) number of the connecting
+ The number of currently active sessions. If a maxmind database has been
+ provided, the labels are populated:
+ * The `asn` label is the [ASN](https://en.wikipedia.org/wiki/Autonomous_system_(Internet)) number of the connecting
client.
* The `ip_prefix`label is the IP prefix of the connecting client.
@@ -69,7 +87,7 @@ The proxy exposes the following metrics around sessions:
## Filter Metrics
-* `quilkin_filter_read_duration_seconds{filter}`
+* `quilkin_filter_read_duration_seconds{filter}`
The duration it took for a `filter`'s `read` implementation to execute.
* The`filter` label is the name of the filter being executed.
@@ -79,7 +97,7 @@ The proxy exposes the following metrics around sessions:
The duration it took for a `filter`'s `write` implementation to execute.
* The `filter` label is the name of the filter being executed.
-Each individual Filter can also expose it's own metrics. See the
-[list of build in Filters](../filters.md#built-in-filters) for more details.
+Each individual Filter can also expose it's own metrics. See the
+[list of build in Filters](./filters.md#built-in-filters) for more details.
-[session-metrics]: #session-metrics
\ No newline at end of file
+[session-metrics]: #session-metrics
diff --git a/docs/src/xds.md b/docs/src/services/xds.md
similarity index 86%
rename from docs/src/xds.md
rename to docs/src/services/xds.md
index dcfe8b05d4..c1b9f4cfa8 100644
--- a/docs/src/xds.md
+++ b/docs/src/services/xds.md
@@ -1,4 +1,23 @@
-# Dynamic Configuration using xDS Management Servers
+# xDS Control Plane
+
+| services | ports | Protocol |
+|----------|-------|-----------|
+| xDS | 7800 | gRPC(IPv4) |
+
+For multi-cluster integration, Quilkin provides a `manage` service, that can be
+used with a number of configuration discovery providers to provide cluster
+configuration multiple [`proxy`s](./proxy.md). With each provider automationing the
+complexity of a full xDS management control plane via integrations with popular
+projects and common architecture patterns.
+
+To view all the providers and options for the `manage` subcommand, run:
+
+```shell
+$ quilkin manage --help
+{{#include ../../../target/quilkin.manage.commands}}
+```
+
+## Overview
In addition to static configuration provided upon startup, a Quiklin proxy's configuration can also be updated at runtime. The proxy can be configured on startup to talk to a set of management servers which provide it with updates throughout its lifecycle.
@@ -32,8 +51,8 @@ Since the range of resources configurable by the xDS API extends that of Quilkin
## Connecting to an xDS management server
Connecting a Quilkin proxy to an xDS management server can be implemented via providing one or more URLs to
-the `management_servers` [command line](../api/quilkin/cli/struct.Proxy.html#structfield.management_server) or
-[file configuration](./file-configuration.md#dynamic-configuration).
+the `management_servers` [command line](../../api/quilkin/cli/struct.Proxy.html#structfield.management_server) or
+[file configuration](../deployment/configuration.md#dynamic-configuration).
[xDS]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol#xds-rest-and-grpc-protocol
@@ -48,15 +67,14 @@ the `management_servers` [command line](../api/quilkin/cli/struct.Proxy.html#str
[clapolicy]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/endpoint/v3/endpoint.proto#config-endpoint-v3-clusterloadassignment-policy
[locality]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/base.proto#config-core-v3-locality
[socket addresses]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-address
-[filters-doc]: ./filters.md
+[filters-doc]: ./proxy/filters.md
[listener-resource]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener
[xds-filters]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#envoy-v3-api-msg-config-listener-v3-filter
[xds-filter-chain]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#config-listener-v3-filterchain
[xds-variants]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol#variants-of-the-xds-transport-protocol
[filter-protos]: https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/proto/quilkin/filters
-[filters-doc]: ./filters.md
[xds-endpoint-metadata]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/base.proto#envoy-v3-api-msg-config-core-v3-metadata
-[endpoint-metadata]: proxy/concepts.md#endpoint-metadata
+[endpoint-metadata]: proxy.md#endpoint-metadata
[control-plane]: https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/xds
[Kubernetes]: https://kubernetes.io/
diff --git a/docs/src/services/xds/metrics.md b/docs/src/services/xds/metrics.md
new file mode 100644
index 0000000000..488a2b6a06
--- /dev/null
+++ b/docs/src/services/xds/metrics.md
@@ -0,0 +1,67 @@
+# xDS Metrics
+
+## Proxy Mode
+
+Quilkin exposes the following metrics around the management servers and its resources when running as a
+[UDP Proxy](../proxy.md):
+
+- `quilkin_xds_connected_state` (Gauge)
+
+ A boolean that indicates whether or not the proxy is currently connected to a management server. A value `1` means that the proxy is connected while `0` means that it is not connected to any server at that point in time.
+
+- `quilkin_xds_update_attempt_total` (Counter)
+
+ The total number of attempts made by a management server to configure the proxy. This is equivalent to the total number of configuration updates received by the proxy from a management server.
+
+- `quilkin_xds_update_success_total` (Counter)
+
+ The total number of successful attempts made by a management server to configure the proxy. This is equivalent to the total number of configuration updates received by the proxy from a management server and was successfully applied by the proxy.
+
+- `quilkin_xds_update_failure_total` (Counter)
+
+ The total number of unsuccessful attempts made by a management server to configure the proxy. This is equivalent to the total number of configuration updates received by the proxy from a management server and was rejected by the proxy (e.g due to a bad/inconsistent configuration).
+
+- `quilkin_xds_requests_total` (Counter)
+
+ The total number of [DiscoveryRequest]s made by the proxy to management servers. This tracks messages flowing in the direction from the proxy to the management server.
+
+
+## xDS Provider Mode
+
+The following metrics are exposed when Quilkin is running as an [xDS provider](../xds.md).
+
+- `quilkin_management_server_connected_proxies` (Gauge)
+
+ The number of proxies currently connected to the server.
+- `quilkin_management_server_discovery_requests_total{request_type}` (Counter)
+
+ The total number of xDS Discovery requests received across all proxies.
+ - `request_type` = `type.googleapis.com/envoy.config.cluster.v3.Cluster` | `type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment` | `type.googleapis.com/envoy.config.listener.v3.Listener`
+ Type URL of the requested resource
+- `quilkin_management_server_discovery_responses_total` (Counter)
+
+ The total number of xDS Discovery responses sent back across all proxies in response to Discovery Requests.
+ Each Discovery response sent corresponds to a configuration update for some proxy.
+ - `request_type` = `type.googleapis.com/envoy.config.cluster.v3.Cluster` | `type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment` | `type.googleapis.com/envoy.config.listener.v3.Listener`
+ Type URL of the requested resource
+- `quilkin_management_server_endpoints_total` (Gauge)
+
+ The number of active endpoints discovered by the server. The number of active endpoints
+ correlates with the size of the cluster configuration update sent to proxies.
+- `quilkin_management_server_snapshot_generation_errors_total` (Counter)
+
+ The total number of errors encountered while generating a configuration snapshot update for a proxy.
+- `quilkin_management_server_snapshots_generated_total` (Counter)
+
+ The total number of configuration snapshot generated across all proxies. A snapshot corresponds
+ to a point in time view of a proxy's configuration. However it does not necessarily correspond
+ to a proxy update - a proxy only gets the latest snapshot so it might miss intermediate
+ snapshots if it lags behind.
+- `quilkin_management_server_snapshots_cache_size` (Gauge)
+
+ The current number of snapshots in the in-memory snapshot cache. This corresponds 1-1 to
+ proxies that connect to the server. However the number may be slightly higher than the number
+ of connected proxies since snapshots for disconnected proxies are only periodically cleared
+ from the cache.
+
+[DiscoveryRequest]: https://www.envoyproxy.io/docs/envoy/v1.22.0/api-v3/service/discovery/v3/discovery.proto.html?highlight=discoveryrequest#service-discovery-v3-discoveryrequest
diff --git a/docs/src/services/xds/providers/agones.md b/docs/src/services/xds/providers/agones.md
new file mode 100644
index 0000000000..c61a49658c
--- /dev/null
+++ b/docs/src/services/xds/providers/agones.md
@@ -0,0 +1,74 @@
+# Agones xDS Provider
+
+The [Agones] xDS Provider is built to simplify Quilkin integration with Agones
+game server hosting on top of [Kubernetes](https://kubernetes.io).
+
+This provider watches for changes in Agones
+[`GameServer` resources](https://agones.dev/site/docs/getting-started/create-gameserver/) in a cluster, and
+utilises that information to provide [Endpoint][Endpoints] information to connected Quilkin proxies.
+
+> Currently, the Agones provider can only discover resources within the cluster it is running in.
+
+## Endpoint Configuration
+
+This provider watches the Kubernetes clusters for `Allocated`
+[Agones GameServers](https://agones.dev/site/docs/reference/gameserver/#gameserver-state-diagram)
+and exposes their IP address and Port as [Endpoints] to any connected Quilkin proxies.
+
+> Since an Agones GameServer can have multiple ports exposed, if multiple ports are in
+> use, the server will pick the first port in the port list.
+
+By default the Agones xDS provider will look in the `default` namespace for any `GameServer` resources, but it can be
+configured via the `--gameservers-namespace` argument.
+
+### Access Tokens
+
+The set of [access tokens](../../proxy.md#specialist-endpoint-metadata) for the associated Endpoint can be
+set by adding a comma separated standard base64 encoded strings. This must be added under an annotation
+`quilkin.dev/tokens` in the
+[GameServer](https://agones.dev/site/docs/reference/agones_crd_api_reference/#agones.dev/v1.GameServer)'s metadata.
+
+For example:
+
+```yaml
+annotations:
+ # Sets two tokens for the corresponding endpoint with values 1x7ijy6 and 8gj3v2i respectively.
+ quilkin.dev/tokens: MXg3aWp5Ng==,OGdqM3YyaQ==
+```
+
+## Filter Configuration
+
+The Agones provider watches for a singular [`ConfigMap`](https://kubernetes.io/docs/concepts/configuration/configmap/)
+that has the label of `quilkin.dev/configmap: "true"`, and any changes that happen to it, and use its contents to
+send Filter configuration to any connected Quilkin proxies.
+
+The `ConfigMap` contents should be a valid Quilkin [file configuration](../../../deployment/configuration.md), but with no Endpoint data.
+
+For example:
+
+```yaml
+{{#include ../../../../../examples/agones-xonotic-xds/xds-control-plane.yaml:config-map}}
+```
+
+By default the Agones xDS provider will look in the `default` namespace for this `ConfigMap`, but it can be
+configured via the `--config-namespace` argument.
+
+## Usage
+
+As an example, the following runs the server with subcommnad `manage agones` against a cluster (using default
+kubeconfig authentication) where Quilkin pods run in the `quilkin` namespace and `GameServer` pods run in the
+`gameservers` namespace:
+
+```sh
+quilkin manage agones --config-namespace quilkin --gameservers-namespace gameservers
+```
+
+For a full referenmce of deploying this provider in a Kubernetes cluster, with appropriate [Deployments], [Services],
+and [RBAC] Rules, there is an [Agones, xDS and Xonotic example][example].
+
+[Agones]: https://agones.dev
+[Endpoints]: ../../proxy.md#endpoints
+[Deployments]: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
+[Services]: https://kubernetes.io/docs/concepts/services-networking/service/
+[RBAC]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
+[example]: https://github.com/googleforgames/quilkin/tree/{{GITHUB_REF_NAME}}/examples/agones-xonotic-xds
diff --git a/docs/src/services/xds/providers/filesystem.md b/docs/src/services/xds/providers/filesystem.md
new file mode 100644
index 0000000000..0c75a22267
--- /dev/null
+++ b/docs/src/services/xds/providers/filesystem.md
@@ -0,0 +1,42 @@
+# Filesystem xDS Provider
+
+The filesystem provider watches a configuration file on disk and sends updates to proxies whenever that file changes.
+
+It can be started with using subcommand `manage file` as the following:
+```sh
+quilkin manage file quilkin.yaml
+```
+
+We run this on port 1800, in this example, in case you are running this locally, and the
+default port is taken up by an existing Quilkin proxy.
+
+After running this command, any proxy that connects to port 18000 will receive updates as configured in `config.yaml`
+file.
+
+You can find the configuration file schema in [Configuration][configuration].
+
+Example:
+
+```rust
+# let yaml = "
+version: v1alpha1
+filters:
+ - name: quilkin.filters.debug.v1alpha1.Debug
+ config:
+ id: hello
+clusters:
+ cluster-a:
+ localities:
+ - endpoints:
+ - address: 123.0.0.1:29
+ metadata:
+ 'quilkin.dev':
+ tokens:
+ - 'MXg3aWp5Ng=='
+# ";
+# let config = quilkin::config::Config::from_reader(yaml.as_bytes()).unwrap();
+# assert_eq!(config.filters.load().len(), 1);
+# quilkin::Proxy::try_from(config).unwrap();
+```
+
+[configuration]: ../../../deployment/configuration.md
diff --git a/docs/src/using.md b/docs/src/using.md
deleted file mode 100644
index 7352fe0de8..0000000000
--- a/docs/src/using.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Using Quilkin
-
-There are two choices for running Quilkin:
-
-* Binary
-* Container image
-
-## Binary
-
-The release binary can be downloaded from the
-[Github releases page](https://github.com/googleforgames/quilkin/releases).
-
-## Container Image
-
-For each [release](https://github.com/googleforgames/quilkin/releases), there is a container image built and
-hosted on Google Cloud [Artifact Registry](https://cloud.google.com/artifact-registry).
-
-The latest production release can be found under the tag:
-
-```
-us-docker.pkg.dev/quilkin/release/quilkin:{{QUILKIN_VERSION}}
-```
-
-Which can be browsed as [us-docker.pkg.dev/quilkin/release/quilkin](https://us-docker.pkg.dev/quilkin/release/quilkin).
-
-The [entrypoint](https://docs.docker.com/engine/reference/builder/#entrypoint) of the container is to run `/quilkin`
-with no arguments, therefore arguments will need to be supplied. See the [documentation below](#command-line-interface)
-for all command line options.
-
-## Command-Line Interface
-
-Quilkin provides a variety of different commands depending on your use-case.
-The primary entrypoint of the process is `run`, which runs Quilkin as a reverse
-UDP proxy. To see a basic usage of the command-line interface run through the
-[netcat with Quilkin quickstart](./quickstarts/netcat.md).
-
-For more advanced usage, checkout the [`quilkin::Cli`] documentation or run:
-
-```shell
-$ quilkin --help
-{{#include ../../target/quilkin.commands}}
-```
-
-## File Based Configuration
-
-For use cases that utilise functionality such as:
-
-* A static set of Filters
-* Multiple static Endpoints
-* Static metadata on Endpoints
-
-Quilkin also provides a yaml based config file as well.
-See the [File Configuration](./file-configuration.md) documentation for details.
-
-## Logging
-By default Quilkin will log `INFO` level events, you can change this by setting
-the `RUST_LOG` environment variable. See [`log` documentation][log-docs] for
-more advanced usage.
-
-> If you are debugging Quilkin set the `RUST_LOG` environemnt variable to `quilkin=trace`, to filter trace level
-> logging to only Quilkin components.
-
-[log-docs]: https://docs.rs/env_logger/0.9.0/env_logger/#enabling-logging
-[`quilkin::Cli`]: ../api/quilkin/struct.Cli.html
diff --git a/docs/src/xds/builtin.md b/docs/src/xds/builtin.md
deleted file mode 100644
index 6513e96470..0000000000
--- a/docs/src/xds/builtin.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Quilkin Built-in xDS Providers
-
-To make xDS integration easier, Quilkin can be run in "xDS Provider Mode".
-
-In this mode, rather than run Quilkin as a proxy, Quilkin will start an xDS management server on the
-[Local Port](../proxy/concepts.md#local-port),
-with each provider abstracting away the complexity of a full xDS management control plane via integrations with
-popular projects and artchitecture patterns.
-
-This is driven by Quilkin being [executed](../using.md#command-line-interface) via the
-[`manage` subcommand](../../api/quilkin/cli/struct.Manage.html), and specifying which provider to be used.
-
-To view all the providers and options for the `manage` subcommand, run:
-
-```shell
-$ quilkin manage --help
-{{#include ../../../target/quilkin.manage.commands}}
-```
-
diff --git a/docs/src/xds/metrics.md b/docs/src/xds/metrics.md
index 10b1619041..2d6b505888 100644
--- a/docs/src/xds/metrics.md
+++ b/docs/src/xds/metrics.md
@@ -64,4 +64,4 @@ The following metrics are exposed when Quilkin is running as an [xDS provider](b
of connected proxies since snapshots for disconnected proxies are only periodically cleared
from the cache.
-[DiscoveryRequest]: https://www.envoyproxy.io/docs/envoy/v1.22.0/api-v3/service/discovery/v3/discovery.proto.html?highlight=discoveryrequest#service-discovery-v3-discoveryrequest
\ No newline at end of file
+[DiscoveryRequest]: https://www.envoyproxy.io/docs/envoy/v1.22.0/api-v3/service/discovery/v3/discovery.proto.html?highlight=discoveryrequest#service-discovery-v3-discoveryrequest
diff --git a/src/cli.rs b/src/cli.rs
index fd8e8fcaa9..21392876a5 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -35,6 +35,7 @@ mod manage;
mod proxy;
const ETC_CONFIG_PATH: &str = "/etc/quilkin/quilkin.yaml";
+const PORT_ENV_VAR: &str = "QUILKIN_PORT";
/// The Command-Line Interface for Quilkin.
#[derive(clap::Parser)]
diff --git a/src/cli/manage.rs b/src/cli/manage.rs
index 66080607a8..8e1aaa9de9 100644
--- a/src/cli/manage.rs
+++ b/src/cli/manage.rs
@@ -14,12 +14,14 @@
* limitations under the License.
*/
+pub const PORT: u16 = 7800;
+
/// Runs Quilkin as a xDS management server, using `provider` as
/// a configuration source.
#[derive(clap::Args, Clone)]
pub struct Manage {
- #[clap(short, long, env = "QUILKIN_PORT")]
- port: Option,
+ #[clap(short, long, env = super::PORT_ENV_VAR, default_value_t = PORT)]
+ port: u16,
/// The configuration source for a management server.
#[clap(subcommand)]
pub provider: Providers,
@@ -48,9 +50,7 @@ pub enum Providers {
impl Manage {
pub async fn manage(&self, config: std::sync::Arc) -> crate::Result<()> {
- if let Some(port) = self.port {
- config.port.store(port.into());
- }
+ config.port.store_if_unset(self.port.into());
let provider_task = {
const PROVIDER_RETRIES: u32 = 25;
diff --git a/src/cli/proxy.rs b/src/cli/proxy.rs
index ef6cb8f1de..534976a8f6 100644
--- a/src/cli/proxy.rs
+++ b/src/cli/proxy.rs
@@ -19,6 +19,8 @@ use std::net::SocketAddr;
#[cfg(doc)]
use crate::filters::FilterFactory;
+pub const PORT: u16 = 7777;
+
/// Run Quilkin as a UDP reverse proxy.
#[derive(clap::Args, Clone)]
#[non_exhaustive]
@@ -30,8 +32,8 @@ pub struct Proxy {
#[clap(long, env)]
pub mmdb: Option,
/// The port to listen on.
- #[clap(short, long, env = "QUILKIN_PORT")]
- pub port: Option,
+ #[clap(short, long, env = super::PORT_ENV_VAR, default_value_t = PORT)]
+ pub port: u16,
/// One or more socket addresses to forward packets to.
#[clap(short, long, env = "QUILKIN_DEST")]
pub to: Vec,
@@ -44,9 +46,7 @@ impl Proxy {
config: std::sync::Arc,
shutdown_rx: tokio::sync::watch::Receiver<()>,
) -> crate::Result<()> {
- if let Some(port) = self.port {
- config.port.store(port.into());
- }
+ config.port.store_if_unset(self.port.into());
let _mmdb_task = self.mmdb.clone().map(|source| {
tokio::spawn(async move {
diff --git a/src/config.rs b/src/config.rs
index ffd7a18b64..d8c48eccc5 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -70,7 +70,7 @@ pub struct Config {
#[serde(default)]
#[schemars(with = "Vec::")]
pub management_servers: Slot>,
- #[serde(default = "default_proxy_port")]
+ #[serde(default = "Slot::::empty")]
pub port: Slot,
#[schemars(with = "Option")]
pub version: Slot,
@@ -221,7 +221,7 @@ impl Default for Config {
management_servers: <_>::default(),
maxmind_db: Slot::empty(),
metrics: <_>::default(),
- port: default_proxy_port(),
+ port: Slot::empty(),
version: <_>::default(),
}
}
@@ -260,10 +260,6 @@ fn default_proxy_id() -> Slot {
Slot::from(sys_info::hostname().unwrap_or_else(|_| Uuid::new_v4().as_hyphenated().to_string()))
}
-fn default_proxy_port() -> Slot {
- Slot::from(7000)
-}
-
#[derive(Clone, Debug, Deserialize, Eq, Serialize, JsonSchema, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Admin {
@@ -273,7 +269,7 @@ pub struct Admin {
impl Default for Admin {
fn default() -> Self {
Admin {
- address: (std::net::Ipv4Addr::UNSPECIFIED, 9091).into(),
+ address: (std::net::Ipv4Addr::UNSPECIFIED, 8000).into(),
}
}
}
@@ -398,7 +394,6 @@ mod tests {
}))
.unwrap();
- assert_eq!(*config.port.load(), 7000);
assert!(config.id.load().len() > 1);
}
diff --git a/src/config/slot.rs b/src/config/slot.rs
index 6c43517562..48471b8a4c 100644
--- a/src/config/slot.rs
+++ b/src/config/slot.rs
@@ -90,6 +90,13 @@ impl Slot {
pub fn remove(&self) {
self.store_opt(None);
}
+
+ /// Replaces the data if the slot is empty.
+ pub fn store_if_unset(&self, value: Arc) {
+ if self.inner.load().is_none() {
+ self.store(value);
+ }
+ }
}
impl Slot {
diff --git a/src/lib.rs b/src/lib.rs
index 9507a0abdc..f3c4050af5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -46,17 +46,17 @@ pub(crate) use self::maxmind_db::MaxmindDb;
#[cfg(doctest)]
mod external_doc_tests {
- #![doc = include_str!("../docs/src/filters.md")]
- #![doc = include_str!("../docs/src/proxy/filters/capture.md")]
- #![doc = include_str!("../docs/src/proxy/filters/compress.md")]
- #![doc = include_str!("../docs/src/proxy/filters/concatenate_bytes.md")]
- #![doc = include_str!("../docs/src/proxy/filters/debug.md")]
- #![doc = include_str!("../docs/src/proxy/filters/firewall.md")]
- #![doc = include_str!("../docs/src/proxy/filters/load_balancer.md")]
- #![doc = include_str!("../docs/src/proxy/filters/local_rate_limit.md")]
- #![doc = include_str!("../docs/src/proxy/filters/match.md")]
- #![doc = include_str!("../docs/src/proxy/filters/timestamp.md")]
- #![doc = include_str!("../docs/src/proxy/filters/token_router.md")]
- #![doc = include_str!("../docs/src/proxy/filters/writing_custom_filters.md")]
- #![doc = include_str!("../docs/src/xds/providers/filesystem.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/capture.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/compress.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/concatenate_bytes.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/debug.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/firewall.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/load_balancer.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/local_rate_limit.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/match.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/timestamp.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/token_router.md")]
+ #![doc = include_str!("../docs/src/services/proxy/filters/writing_custom_filters.md")]
+ #![doc = include_str!("../docs/src/services/xds/providers/filesystem.md")]
}