Skip to content

Commit

Permalink
FGA local development setup (#5059)
Browse files Browse the repository at this point in the history
* add up-to-date model def

* add compose

* fga scripts

* whitespace

* damn whitespace

* consistent calls

* use pnpm from nix

* expand comment

* add comments

* whitespace nightmares

* no need to if

* fix command check

* fix(shell) Added FGA to start-minimal-webpack.

* fix stupid openfga/cli container issue

* restore dependency

* split podman/docker

---------

Co-authored-by: Sean Parsons <[email protected]>
  • Loading branch information
ruggi and seanparsons authored Mar 18, 2024
1 parent 315fdfe commit b3cac3e
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 2 deletions.
20 changes: 18 additions & 2 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,20 @@ let
set -e
cd $(${pkgs.git}/bin/git rev-parse --show-toplevel)/utopia-remix
${pnpm}/bin/pnpm install
${pnpm}/bin/pnpm exec prisma generate
PORT=8000 DATABASE_URL="postgres://$(whoami):postgres@localhost:5432/utopia" ${pnpm}/bin/pnpm run dev
${pnpm}/bin/pnpm exec prisma generate > /dev/null
PNPM=${pnpm}/bin/pnpm PORT=8000 DATABASE_URL="postgres://$(whoami):postgres@localhost:5432/utopia" LOCAL=true ./run-remix.sh
'')
(pkgs.writeScriptBin "watch-fga" ''
#!/usr/bin/env bash
set -e
cd $(${pkgs.git}/bin/git rev-parse --show-toplevel)/utopia-remix
./fga-run.sh
'')
(pkgs.writeScriptBin "fga-create-store" ''
#!/usr/bin/env bash
set -e
cd $(${pkgs.git}/bin/git rev-parse --show-toplevel)/utopia-remix
./fga-create-store.sh
'')
];

Expand Down Expand Up @@ -639,6 +651,8 @@ let
send-keys -t :9 watch-vscode-build-extension-only C-m \; \
new-window -n "PostgreSQL" \; \
send-keys -t :10 start-postgres C-m \; \
new-window -n "FGA" \; \
send-keys -t :11 watch-fga C-m \; \
select-window -t :1 \;
'')
(pkgs.writeScriptBin "start-full" ''
Expand Down Expand Up @@ -684,6 +698,8 @@ let
send-keys -t :9 watch-vscode-build-extension-only C-m \; \
new-window -n "PostgreSQL" \; \
send-keys -t :10 start-postgres C-m \; \
new-window -n "FGA" \; \
send-keys -t :11 watch-fga C-m \; \
select-window -t :1 \;
'')
(pkgs.writeScriptBin "start-full-webpack" ''
Expand Down
81 changes: 81 additions & 0 deletions utopia-remix/docker-compose.fga.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
services:
postgres:
image: postgres:14
container_name: postgres
command: postgres -c 'max_connections=100'
networks:
- default
ports:
- '54323:5432'
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 5s
retries: 5

migrate:
depends_on:
postgres:
condition: service_healthy
image: openfga/openfga:latest
container_name: migrate
environment:
- OPENFGA_DATASTORE_ENGINE=postgres
- OPENFGA_DATASTORE_URI=postgres://postgres:password@postgres:5432/postgres?sslmode=disable
command: migrate
networks:
- default

openfga:
depends_on:
migrate:
condition: service_completed_successfully
image: openfga/openfga:latest
container_name: openfga
command: run
environment:
- OPENFGA_DATASTORE_ENGINE=postgres
- OPENFGA_DATASTORE_URI=postgres://postgres:password@postgres:5432/postgres?sslmode=disable
- OPENFGA_DATASTORE_MAX_OPEN_CONNS=100 #see postgres container
- OPENFGA_PLAYGROUND_ENABLED=true
networks:
- default
ports:
- '8003:8080' #http
# - '8081:8081' #grpc
# - '3002:3000' #playground
# - "2112:2112" #prometheus metrics
healthcheck:
test: ['CMD', '/usr/local/bin/grpc_health_probe', '-addr=openfga:8081']
interval: 5s
timeout: 30s
retries: 3

# Two separate manual services for Docker and Podman because they behave differently :(
utopia-fga-model-docker:
profiles:
- manual
depends_on:
openfga:
condition: service_healthy
image: openfga/cli:latest
container_name: utopia-fga-model-docker
volumes:
- ./fga/model.fga:/model.fga
command: store create --name utopia-local --model /model.fga --api-url http://openfga:8080
utopia-fga-model-podman:
profiles:
- manual
image: alpine:3.19.1
container_name: utopia-fga-model-podman
volumes:
- ./fga/model.fga:/model.fga
command: >
sh -c "
wget -q https://github.com/openfga/cli/releases/download/v0.2.7/fga_0.2.7_linux_arm64.tar.gz
tar -xzf fga_0.2.7_linux_arm64.tar.gz
./fga store create --name utopia-local --model /model.fga --api-url http://openfga:8080
"
45 changes: 45 additions & 0 deletions utopia-remix/fga-create-store.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

# Create a new store based on the fga/model.fga file against the local FGA server,
# then parse the generated Store ID and save it into the .env file.

set -e

HOST_ENV_KEY="FGA_API_HOST"
STORE_ENV_KEY="FGA_STORE_ID"

# Only run this if the .env file uses the local FGA store
if ! grep -qE "^[^#]*\b${HOST_ENV_KEY}\b=['\"]?localhost" .env; then
echo "The FGA_API_HOST is either not defined or not set to localhost, so I won't do anything."
exit
fi

if type docker &> /dev/null; then
RUNTIME=docker
elif type podman &> /dev/null; then
RUNTIME=podman
else
echo "The docker or podman commands are not found."
exit
fi

SERVICE_NAME="utopia-fga-model-${RUNTIME}"

echo "* Creating store…"
${RUNTIME} compose -f docker-compose.fga.yml up ${SERVICE_NAME}

# Note: it would be awesome to just use jq here, but there's no guarantee it
# will be available on the host machine, so this is just doing a simple regex
# match since the JSON output of the FGA CLI is simple enough.
echo "* Parsing logs…"
STORE_ID=$( ${RUNTIME} logs -f ${SERVICE_NAME} | tail -n1 | grep -o '"id":"[^"]*"' | awk -F':' '{print $2}' | tr -d '"' )

echo "=> Obtained store id ${STORE_ID}"

STORE_ENV_LINE="${STORE_ENV_KEY}=\"${STORE_ID}\" # ** GENERATED BY fga-create-store.sh **"

grep -vE "\b${STORE_ENV_KEY}\b=" .env > .env.temp
mv .env.temp .env
echo "${STORE_ENV_LINE}" >> .env

echo "=> Updated .env file"
26 changes: 26 additions & 0 deletions utopia-remix/fga-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

# Start the FGA local server with either Docker or Podman.

set -e

HOST_ENV_KEY="FGA_API_HOST"
STORE_ENV_KEY="FGA_STORE_ID"

# Only run this if the .env file uses the local FGA store
if ! grep -qE "^[^#]*\b${HOST_ENV_KEY}\b=['\"]?localhost" .env; then
echo "The FGA_API_HOST is either not defined or not set to localhost, so I won't do anything."
echo "If you want to enable the local FGA server, please add FGA_API_HOST=localhost:8003 to your environment variables."
exit
fi

if type docker &> /dev/null; then
RUNTIME=docker
elif type podman &> /dev/null; then
RUNTIME=podman
else
echo "The docker or podman commands are not found."
exit
fi

${RUNTIME} compose -f docker-compose.fga.yml up
26 changes: 26 additions & 0 deletions utopia-remix/fga/model.fga
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
model
schema 1.1

type user

type project
relations
define can_change_owner: owner
define can_comment: collaborator or editor or owner
define can_edit: editor or owner
define can_fork: viewer or collaborator or editor or owner
define can_manage: owner
define can_play: viewer or collaborator or editor or owner
define can_request_access: [user:*]
define can_see_live_changes: collaborator or editor or owner
define can_show_presence: collaborator or editor or owner
define can_view: viewer or collaborator or editor or owner
define collaborator: [user, user:*, group#member]
define creator: [user]
define editor: [user, group#member]
define owner: [user] or creator
define viewer: [user, user:*, group#member]

type group
relations
define member: [user]
23 changes: 23 additions & 0 deletions utopia-remix/run-remix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

## Please run this script from shell.nix with `watch-remix` or provide the
## PNPM= environment variable with the pnpm executable path.

set -e

if [ "${LOCAL}" == 'true' ] ; then
# Make sure the .env file exists
touch .env

HOST_ENV_KEY="FGA_API_HOST"
STORE_ENV_KEY="FGA_STORE_ID"

if grep -qE "^[^#]*\b${HOST_ENV_KEY}\b=['\"]?localhost" .env; then
if ! grep -qE "^[^#]*\b${STORE_ENV_KEY}\b=['\"]?.+" .env; then
echo "* FGA is set to run locally, but no FGA_STORE_ID is set. Creating it…"
./fga-create-store.sh
fi
fi
fi

${PNPM} run dev

0 comments on commit b3cac3e

Please sign in to comment.