DRAFT — Preliminary version, do not share. · Version préliminaire, ne pas partager.

The fun CLI

The fun CLI lets you manage Fundamentum from your terminal and your scripts. This guide shows you how to install it, sign in, work with several environments, use the curated commands, and call any Public API operation with fun api.

Before you begin

1. Install the CLI

Download the archive for your platform from https://cli.fundamentum-iot.com:

Platform Archive
Linux (amd64) fundamentum-cli-linux-amd64-<version>.zip
macOS (Apple silicon, arm64) fundamentum-cli-mac-arm64-<version>.zip
Windows (386) fundamentum-cli-windows-386-<version>.zip

On Linux and macOS, extract the fun binary and put it on your PATH:

unzip fundamentum-cli-mac-arm64-<version>.zip
chmod +x fun
sudo mv fun /usr/local/bin/fun

On macOS, Gatekeeper may block the binary the first time you run it because it was downloaded from the internet. Allow it in System Settings → Privacy & Security.

On Windows, the archive contains fun.exe. Extract it to a folder on your PATH.

Check the installation:

fun --version

Check for a newer release at any time with fun check-update. To upgrade, download the new archive and replace the binary.

Optionally, enable shell completion, which also completes the fun api commands:

source <(fun completion zsh)

Replace zsh with bash, fish or powershell. See fun completion <shell> --help to install it permanently.

2. Sign in

fun login

The CLI asks for:

  1. a context name: press Enter for default;
  2. the API endpoint: press Enter for https://api.fundamentum-iot.com;
  3. the OAuth endpoint: press Enter for https://oauth.fundamentum-iot.com.

Your browser opens on the Fundamentum sign-in page, where you sign in as usual, including with single sign-on. The CLI then saves your token in contexts.json in its configuration directory. fun config dir prints where that is.

When the token expires, run fun login again and give the same context name: the CLI refreshes the token and keeps your endpoints.

3. Use a context per environment

A context is a named set of endpoints and a token. Create one per environment or account:

fun login                  # answer "staging" to the context prompt, then the staging endpoints
fun config contexts list

Select a context with --context on any command that calls Fundamentum. Without it, the CLI uses default:

fun functions list --project <project-id> --context staging

To change the endpoints of an existing context, run fun login --override.

4. Use the curated commands

Curated commands cover tasks that need more than one API call. Their names are versioned with the CLI, so they are the right choice for scripts that must keep working.

Forward a port of a device to your machine, for example to reach its web server on port 80 at localhost:8080:

fun devices port-forward -p <project-id> -r <registry-id> -s <serial-number> -l 8080 -d 80

Press any key to stop forwarding. See Remote terminal and port forwarding.

Send a file to a device, and fetch one back:

fun devices transfer cloud-to-device -p <project-id> -r <registry-id> -s <serial-number> \
  --file ./config.bin --remote-path /etc/app/config.bin

fun devices transfer device-to-cloud -p <project-id> -r <registry-id> -s <serial-number> \
  --remote-path /var/log/app.log --name app.log

The local file must be a relative path inside the current directory. See File transfers.

Create, upload and invoke a cloud function:

fun functions new decoder --project <project-id> --language go --description "Decode sensor frames"
fun functions upload decoder ./decoder.wasm
echo '{"frame":"0a1b"}' | fun functions invoke --name decoder
fun functions executions list --name decoder

decoder is a local name the CLI saves in functions.json, so you don't need to repeat the project and function IDs. See Cloud functions.

5. Call any Public API operation with fun api

fun api exposes every operation of the Public API, generated from its OpenAPI specs. New operations become available without a new CLI release.

Download the specs once, and again whenever you need newly published operations:

fun api refresh

Discover the operations, from the version down to the operation:

fun api v1 --help
fun api v1 device --help
fun api v1 device get-device --help

Call an operation. Path parameters are required flags, and every parameter is a kebab-case flag:

fun api v1 device get-device --project-id <project-id> --device-id <device-id>

Send a body inline, from a file, or from stdin:

fun api v2 service-accounts create-service-account --project-id <project-id> \
  --body-file service-account.json

Group and operation names come from the spec, so they can change when the specs change. Use fun api for exploration and one-off calls, and prefer curated commands in long-lived automation.

6. Script with the CLI

The CLI keeps stdout for JSON so you can pipe it:

fun api v2 licenses list-licenses --project-id <project-id> --data-only | jq '.[].id'
fun api v1 device list-devices --project-id <project-id> --page 1 > devices.json
fun api v2 registries create-registry --project-id <project-id> --body-file registry.json --dry-run

In CI, avoid the browser sign-in: define the context with environment variables and a service-account token:

export FUN_CONTEXT_FUNDAMENTUM_IOT_ENDPOINT=https://api.fundamentum-iot.com
export FUN_CONTEXT_API_KEY="$SERVICE_ACCOUNT_TOKEN"
fun functions invoke --project <project-id> --function-id <function-id> --input-file input.json

Store the token in your CI secret store, never in the repository. See Authentication to create a service account and its token.

What's next