Skip to content

Commit

Permalink
Improve docs for uplink REST API
Browse files Browse the repository at this point in the history
- Improve installation instructions
- Add OAuth section
- Add metrics response example

Signed-off-by: Han Verstraete (OpenFaaS Ltd) <[email protected]>
  • Loading branch information
welteki authored and alexellis committed Dec 10, 2024
1 parent 781573a commit 4d046f7
Showing 1 changed file with 174 additions and 45 deletions.
219 changes: 174 additions & 45 deletions docs/uplink/rest-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,47 @@ A quick note on TLS: when you expose the uplink API over the Internet, you shoul

## Installation

The Uplink Client API can be enabled through the helm chart. Update the `values.yaml`:
The REST API is part of the client-api component, and is disabled by default.
You'll need to configure authentication, then update the values.yaml file and install the chart again.

An access token needs to be created for the Client API before it can be deployed.

```sh
# Generate a new access token
export token=$(openssl rand -base64 32|tr -d '\n')
echo -n $token > $HOME/.inlets/client-api

# Store the access token in a secret in the inlets namespace.
kubectl create secret generic \
client-api-token \
-n inlets \
--from-file client-api-token=$HOME/.inlets/client-api
```

This token can be used to authenticate with the API.

> See the [OAuth configuration](#configure-oauth) section for instructions on how to enable OAuth.
Add the following parameters to your uplink `values.yaml` file and update the deployment:

```yaml
clientApi:
enable: true
enable: true

# Domain used for client API ingress
domain: clientapi.example.com

# Domain used for client API ingress
domain: clientapi.example.com
tls:
ingress:
# Optionally enable ingress for the Client API
enabled: true
```
## Authentication
The Inlets Uplink client API supports authentication through API tokens.
The Inlets Uplink client API supports authentication through a static API token or using OAuth.
### Static API token
The authentication token can be retrieved from the cluster at any time by an administrator.
Expand All @@ -28,76 +56,145 @@ export TOKEN=$(kubectl get secret -n inlets client-api-token \
| base64 --decode)
```

## Tunnels
Use the token as bearer token in the `Authorization` header when making requests to the API.

### OAuth

If you have OAuth enabled you can obtain a token from your provider that can be used to invoke the Uplink Client API.

The example uses the client credentials grant. Replace the token url, client id and client secret with the values obtained from your identity provider.

```sh
export IDP_TOKEN_URL="https://myprovider.example.com/token"
export CLIENT_ID="inlets-uplink"
export CLIENT_SECRET="$(cat ./client-secret.txt)"

curl -S -L -X POST "${IDP_TOKEN_URL}" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "client_id=${CLIENT_ID}" \
--data-urlencode "client_secret=${CLIENT_SECRET}" \
--data-urlencode 'scope=openid' \
--data-urlencode 'grant_type=client_credentials'
```

Use the token as bearer token in the `Authorization` header when making requests to the API.

```sh
export CLIENT_API="https://clienapi.example.com"
export NAME="acmeco"
export NAMESPACE="acmeco"

curl -i \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
```

## Tunnel management

We will be create an tunnel named `acmeco` in the `acmeco` namespace in the API examples.

### Get a tunnel

```sh
export CLIENT_API="https://clienapi.example.com"
export NAME="acmeco"
export NAMESPACE="acmeco"

curl -i \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
```

Adding the query parameter `metrics=1` includes additional tunnel metrics in the response like RX and TX and TCP connection rate.

Path parameters:

* `name` - Name of the tunnel.
- `name` - Name of the tunnel.

Query parameters:

* `namespace` - Namespace where the tunnel should be looked up.
* `metrics` - Include tunnel metrics in the response.
- `namespace` - Namespace where the tunnel should be looked up.
- `metrics` - Include tunnel metrics in the response.

Example response with metrics:

```json
{
"name": "acmeco",
"namespace": "acmeco",
"tcpPorts": [80, 443],
"authToken": "TAjFZExVq6qUfnqojwR2HOej347fRXqV3vLexlyoP6GcRZ2SjIUALY8Jdx8",
"connectedClients": 1,
"created": "2024-09-10T14:48:21Z",
"metrics": {
"rx": 195482,
"tx": 32348,
"tcpConnectionRate": 62.99
}
}
```

The metrics section includes rx/tx bytes per second and tcp connection rate over the last 5 minutes.

### List tunnels

```sh
export CLIENT_API="https://clienapi.example.com"
export NAMESPACE="acmeco"

curl -i \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels?namespace=$NAMESPACE"
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels?namespace=$NAMESPACE"
```

Query parameters:

* `namespace` - Namespace where the tunnel should be looked up.
- `namespace` - Namespace where the tunnel should be looked up.

### Create a tunnel

```sh
export CLIENT_API="https://clienapi.example.com"

curl -i \
-X POST \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels"
-d '{ "name": "acmeco", "namespace": "acmeco", "tcpPorts": [ 80, 443 ] }'
-X POST \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels"
-d '{ "name": "acmeco", "namespace": "acmeco", "tcpPorts": [ 80, 443 ] }'
```

### Update a tunnel

```sh
export CLIENT_API="https://clienapi.example.com"

curl -i \
-X PUT \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels"
-d '{ "name": "acmeco", "namespace": "acmeco", "tcpPorts": [ 80, 443, 4222 ] }'
-X PUT \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels"
-d '{ "name": "acmeco", "namespace": "acmeco", "tcpPorts": [ 80, 443, 4222 ] }'
```

### Delete a tunnel

```sh
export CLIENT_API="https://clienapi.example.com"
export NAME="acmeco"
export NAMESPACE="acmeco"

curl -i \
-X DELETE \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
-X DELETE \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
```

Path parameters:

* `name` - Name of the tunnel.
- `name` - Name of the tunnel.

Query parameters:

* `namespace` - Namespace where the tunnel should be looked up.

- `namespace` - Namespace where the tunnel should be looked up.

## Namespace management

Expand All @@ -109,19 +206,23 @@ The `kube-system` and `inlets` namespace can not be used as tunnel namespaces.
List all inlets uplink namespaces. This endpoint will list all namespaces with a label `inlets.dev/uplink=1`.

```sh
export CLIENT_API="https://clienapi.example.com"

curl -i \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/namespace
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/namespace
```
### Create a namespace
```sh
export CLIENT_API="https://clienapi.example.com"
curl -i \
-X POST \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/tunnels/$NAME?namespace=$NAMESPACE"
-d '{ "name": "acmeco" }'
-X POST \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/namespace
-d '{ "name": "acmeco" }'
```

Every namespace created through the API will have the `inlets.dev/uplink=1` label set.
Expand All @@ -130,21 +231,49 @@ The API supports adding additional namespace labels and annotations:

```json
{
"name": "acmeco",
"annotations": {
"customer": "acmeco"
},
"labels": {
"customer": "acmeco"
}
"name": "acmeco",
"annotations": {
"customer": "acmeco"
},
"labels": {
"customer": "acmeco"
}
}
```

### Delete a namespace

```sh
export CLIENT_API="https://clienapi.example.com"
export NAME="acmeco"

curl -i \
-X DELETE \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/namespace/$NAME"
```
-X DELETE \
-H "Authorization: Bearer ${TOKEN}" \
"$CLIENT_API/v1/namespace/$NAME"
```

## Configure OAuth

You can configure any OpenID Connect (OIDC) compatible identity provider for use with Inlets Uplink.

1. Register a new client (application) for Inlets Uplink with your identity provider.
2. Enable the required authentication flows.
The Client Credentials flow is ideal for serve-to-server interactions where there is no direct user involvement. This is the flow we recommend and use in our examples any other authentication flow can be picked depending on your use case.
3. Configure Client API

Update your `values.yaml` file and add to following parameters to the `clientApi` section:

```yaml
clientApi:
# OIDC provider url.
issuerURL: "https://myprovider.example.com"

# The audience is generally the same as the value of the domain field, however
# some issuers like keycloak make the audience the client_id of the application/client.
audience: "clienapi.example.com"
```
The `issuerURL` needs to be set to the url of your provider, eg. `https://accounts.google.com` for google or `https://example.eu.auth0.com/` for Auth0.

The `audience` is usually the client apis public URL although for some providers it can also be the client id.

0 comments on commit 4d046f7

Please sign in to comment.