diff --git a/.gitignore b/.gitignore index 0e392c7a..101e7cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,7 @@ venv.bak/ # -- Tools .coverage + +# -- Provisioning +provisioning/.terraform* +provisioning/terraform.tfstate* diff --git a/Makefile b/Makefile index d15d9294..f7fad6be 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,8 @@ bootstrap: \ build \ migrate-api \ create-api-test-db \ + create-metabase-db \ + seed-metabase \ seed-oidc \ create-superuser .PHONY: bootstrap @@ -65,10 +67,14 @@ logs-api: ## display API server logs (follow mode) @$(COMPOSE) logs -f api .PHONY: logs-api -run: ## run the whole stack - $(COMPOSE) up -d +run: ## run the api server (and dependencies) + $(COMPOSE) up -d api .PHONY: run +run-all: ## run the whole stack + $(COMPOSE) up -d api keycloak metabase +.PHONY: run-all + status: ## an alias for "docker compose ps" @$(COMPOSE) ps .PHONY: status @@ -84,6 +90,11 @@ create-api-test-db: ## create API test database @$(COMPOSE) exec postgresql bash -c 'psql "postgresql://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@$${QUALICHARGE_DB_HOST}:$${QUALICHARGE_DB_PORT}/$${QUALICHARGE_TEST_DB_NAME}" -c "create extension postgis;"' || echo "Duly noted, skipping extension creation." .PHONY: create-api-test-db +create-metabase-db: ## create metabase database + @echo "Creating metabase service database…" + @$(COMPOSE) exec postgresql bash -c 'psql "postgresql://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@$${QUALICHARGE_DB_HOST}:$${QUALICHARGE_DB_PORT}/postgres" -c "create database \"$${MB_DB_DBNAME}\";"' || echo "Duly noted, skipping database creation." +.PHONY: create-metabase-db + drop-api-test-db: ## drop API test database @echo "Droping api service test database…" @$(COMPOSE) exec postgresql bash -c 'psql "postgresql://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@$${QUALICHARGE_DB_HOST}:$${QUALICHARGE_DB_PORT}/postgres" -c "drop database \"$${QUALICHARGE_TEST_DB_NAME}\";"' || echo "Duly noted, skipping database deletion." @@ -94,6 +105,11 @@ drop-api-db: ## drop API database @$(COMPOSE) exec postgresql bash -c 'psql "postgresql://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@$${QUALICHARGE_DB_HOST}:$${QUALICHARGE_DB_PORT}/postgres" -c "drop database \"$${QUALICHARGE_DB_NAME}\";"' || echo "Duly noted, skipping database deletion." .PHONY: drop-api-db +drop-metabase-db: ## drop Metabase database + @echo "Droping metabase service database…" + @$(COMPOSE) exec postgresql bash -c 'psql "postgresql://$${POSTGRES_USER}:$${POSTGRES_PASSWORD}@$${QUALICHARGE_DB_HOST}:$${QUALICHARGE_DB_PORT}/postgres" -c "drop database \"$${MB_DB_DBNAME}\";"' || echo "Duly noted, skipping database deletion." +.PHONY: drop-metabase-db + migrate-api: ## run alembic database migrations for the api service @echo "Running api service database engine…" @$(COMPOSE) up -d --wait postgresql @@ -116,6 +132,16 @@ create-superuser: ## create super user --force .PHONY: create-superuser +seed-metabase: ## seed the Metabase server + @echo "Running metabase service …" + @$(COMPOSE) up -d --wait metabase + @echo "Create metabase initial admin user…" + bin/metabase-init + @echo "Create API data source…" + $(COMPOSE_RUN) terraform init + $(COMPOSE_RUN) terraform apply -auto-approve +.PHONY: seed-metabase + seed-oidc: ## seed the OIDC provider @echo 'Starting OIDC provider…' @$(COMPOSE) up -d keycloak diff --git a/README.md b/README.md index 88f5e295..4984b37a 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,11 @@ make bootstrap > 👉 Cette commande doit préparer votre environnement et builder les images > Docker nécessaires au démarrage de votre environnement. -Une fois votre environnement de travail initialisé, vous pouvez lancer le projet en -utilisant : +Une fois votre environnement de travail initialisé, vous pouvez lancer le projet +en utilisant : ``` -make run +make run-all ``` Les services QualiCharge doivent maintenant tourner sur votre poste : @@ -55,6 +55,16 @@ Et enfin, pour lancer les tests du projet : make test ``` +## Explorer les données collectées avec Metabase + +Si vous avez utilisé la commande `make bootstrap` pour initialiser le projet, +vous devez avoir provisionné une instance de Metabase qui est accessible depuis +un navigateur sur l'URL suivante : +[http://localhost:3000](http://localhost:3000). + +> :bulb: Vous pouvez vous connecter en utilisant le login `admin@example.com` et +> le mot de passe `supersecret`. + ## Utilisation du client d'API et du CLI `qcc` Voir la documentation du projet : [./src/client/](./src/client/) diff --git a/bin/metabase-init b/bin/metabase-init new file mode 100755 index 00000000..9cc35552 --- /dev/null +++ b/bin/metabase-init @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# This script will run at project bootstrap to initialize a metabase instance +# +# It is inspired from the metabase setup script of the metabase terraform provider: +# github.com/bnjns/terraform-provider-metabase + +set -eo pipefail + +# Utilities +declare COMPOSE_RUN="docker compose run --rm -T" +declare CURL="${COMPOSE_RUN} curl" +declare JQ="${COMPOSE_RUN} jq" + +# Vars +declare METABASE_HOST="http://metabase:3000" +declare METABASE_EMAIL="admin@example.com" +declare METABASE_PASSWORD="supersecret" + +# Get the setup token +echo "⚙️ Getting setup token…" +if ! setupToken=$(${CURL} -s --fail "${METABASE_HOST}/api/session/properties" | ${JQ} -er '."setup-token"'); then + echo "Failed to extract setup token" + exit 2 +fi + +echo "⚙️ Configuring metabase…" +${JQ} -n "{ \ + database: null, \ + invite: null, \ + prefs: { \ + allow_tracking: false, \ + site_locale: \"en\", \ + site_name: \"QualiCharge\" \ + }, \ + user: { \ + email: \"${METABASE_EMAIL}\", \ + first_name: \"Admin\", \ + last_name: \"User\", \ + password: \"${METABASE_PASSWORD}\", \ + password_confirm: \"${METABASE_PASSWORD}\", \ + site_name: \"QualiCharge\" \ + }, \ + token: \"${setupToken}\" \ +}" | ${CURL} -s --fail \ + -X POST \ + -H "Content-Type: application/json" \ + -d @- \ + "${METABASE_HOST}/api/setup" + +echo "✅ all done." diff --git a/bin/qcc b/bin/qcc index 7dadaf97..a4022348 100755 --- a/bin/qcc +++ b/bin/qcc @@ -10,6 +10,6 @@ DOCKER_USER="${DOCKER_UID}:${DOCKER_GID}" DOCKER_USER=${DOCKER_USER} \ DOCKER_UID=${DOCKER_UID} \ DOCKER_GID=${DOCKER_GID} \ - docker compose run --rm \ + docker compose run --rm -T \ client \ qcc "$@" diff --git a/docker-compose.yml b/docker-compose.yml index e27695da..a26bbae5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,7 @@ services: env_file: - env.d/postgresql - env.d/api + - env.d/metabase healthcheck: test: - "CMD-SHELL" @@ -30,7 +31,6 @@ services: - ./src/api:/app depends_on: - postgresql - - keycloak client: build: @@ -56,12 +56,44 @@ services: volumes: - ./bin/kc-init:/usr/local/bin/kc-init - # -- tools - dockerize: - image: jwilder/dockerize + metabase: + image: metabase/metabase:v0.50.5 + ports: + - 3000:3000 + env_file: + - env.d/metabase + healthcheck: + test: curl --fail -I http://localhost:3000/api/health || exit 1 + interval: 15s + timeout: 5s + retries: 5 + depends_on: + - postgresql + # -- tools curl: image: curlimages/curl:8.8.0 user: ${DOCKER_USER:-1000} + env_file: + - env.d/metabase volumes: - .:/work + + dockerize: + image: jwilder/dockerize + + jq: + # There is no other tags than latest + image: ddev/ddev-utilities:latest + entrypoint: jq + env_file: + - env.d/metabase + + terraform: + image: hashicorp/terraform:1.8.5 + env_file: + - env.d/terraform + user: ${DOCKER_USER:-1000} + working_dir: /home/terraform + volumes: + - ./provisioning:/home/terraform diff --git a/env.d/metabase b/env.d/metabase new file mode 100644 index 00000000..eecc4e2d --- /dev/null +++ b/env.d/metabase @@ -0,0 +1,8 @@ +MB_DB_DBNAME=metabaseappdb +MB_DB_HOST=postgresql +MB_DB_PASS=pass +MB_DB_PORT=5432 +MB_DB_TYPE=postgres +MB_DB_USER=qualicharge +MB_PASSWORD_COMPLEXITY=weak +MB_SEND_EMAIL_ON_FIRST_LOGIN_FROM_NEW_DEVICE=false diff --git a/env.d/terraform b/env.d/terraform new file mode 100644 index 00000000..a5ced5c6 --- /dev/null +++ b/env.d/terraform @@ -0,0 +1,3 @@ +METABASE_HOST=http://metabase:3000 +METABASE_USERNAME=admin@example.com +METABASE_PASSWORD=supersecret diff --git a/provisioning/main.tf b/provisioning/main.tf new file mode 100644 index 00000000..b7361c83 --- /dev/null +++ b/provisioning/main.tf @@ -0,0 +1,15 @@ +# Database +resource "metabase_database" "qualicharge" { + engine = "postgres" + name = "QualiCharge API" + + details = jsonencode({ + host = "postgresql" + port = 5432 + dbname = "qualicharge-api" + user = "qualicharge" + }) + details_secure = jsonencode({ + password = "pass" + }) +} diff --git a/provisioning/provider.tf b/provisioning/provider.tf new file mode 100644 index 00000000..7c466803 --- /dev/null +++ b/provisioning/provider.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + metabase = { + source = "bnjns/metabase" + version = "0.9.0" + } + } +} + +provider "metabase" { + # Configured using environment variables + # See env.d/terraform +}