Skip to content

Commit

Permalink
Merge branch 'main' into feat/regulation-order-history
Browse files Browse the repository at this point in the history
  • Loading branch information
Lealefoulon committed Jan 21, 2025
2 parents 7ff9170 + 23cd3b8 commit 3114647
Show file tree
Hide file tree
Showing 72 changed files with 1,366 additions and 632 deletions.
6 changes: 2 additions & 4 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ APP_BAC_IDF_DECREES_FILE=data/bac_idf/decrees.json
APP_BAC_IDF_CITIES_FILE=data/bac_idf/cities.csv
DATABASE_URL="postgresql://dialog:dialog@database:5432/dialog"
METABASE_DATABASE_URL="postgresql://dialog:dialog@database:5432/dialog"
APP_DIALOG_BASE_URL=http://nginx
REDIS_URL="redis://redis:6379"
API_ADRESSE_BASE_URL=https://api-adresse.data.gouv.fr
APP_IGN_GEOCODER_BASE_URL=https://data.geopf.fr
Expand All @@ -36,11 +37,8 @@ APP_JOP_ORG_ID=
###< JOP ###
###> Litteralis ###
APP_LITTERALIS_WFS_BASE_URL=https://apps.sogelink.fr
APP_LITTERALIS_ENABLED_ORGS='[]'
###< Litteralis ###
###> MEL ###
APP_MEL_LITTERALIS_CREDENTIALS=
APP_MEL_ORG_ID=
###< MEL ###
###> symfony/messenger ###
# Choose one of the transports below
# MESSENGER_TRANSPORT_DSN=doctrine://default
Expand Down
7 changes: 3 additions & 4 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ APP_CLIENT_TIMEZONE=Etc/GMT-1 # Independant of Daylight Saving Time (DST)
APP_SECRET='$ecretf0rt3st'
APP_EUDONET_PARIS_CREDENTIALS='{"SubscriberLogin": "testSubcriberLogin", "SubscriberPassword": "testSubcriberPassword", "BaseName": "TEST_BASE_NAME", "UserLogin": "testUserLogin", "UserPassword": "testPassword", "UserLang": "lang_00", "ProductName": "api"}'
APP_EUDONET_PARIS_ORG_ID=e0d93630-acf7-4722-81e8-ff7d5fa64b66 # DiaLog org
APP_MEL_LITTERALIS_CREDENTIALS='testuser:testpass'
APP_MEL_ORG_ID=e0d93630-acf7-4722-81e8-ff7d5fa64b66 # DiaLog org
APP_FOUGERES_LITTERALIS_CREDENTIALS='testuser:testpass'
APP_FOUGERES_ORG_ID=e0d93630-acf7-4722-81e8-ff7d5fa64b66 # DiaLog org
APP_LITTERALIS_ENABLED_ORGS='["test"]'
APP_LITTERALIS_ORG_TEST_ID="e0d93630-acf7-4722-81e8-ff7d5fa64b66"
APP_LITTERALIS_ORG_TEST_CREDENTIALS='testuser:testpass'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
MAX_ITEMS_PER_PAGE=1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
name: Litteralis Fougeres Import
name: Litteralis Import

on:
workflow_dispatch:
inputs:
enabled_orgs:
description: "Organisations à intégrer (format : array JSON)"
required: false
default: null
type: string

schedule:
- cron: '15 16 * * 1' # Voir https://crontab.guru/ : tous les lundis à 16h15 GMT

Expand Down Expand Up @@ -45,15 +52,25 @@ jobs:
- name: Init environment variables
run: |
echo "DATABASE_URL=${{ secrets.APP_FOUGERES_IMPORT_DATABASE_URL }}" >> .env.local
echo "DATABASE_URL=${{ secrets.APP_LITTERALIS_IMPORT_DATABASE_URL }}" >> .env.local
echo "BDTOPO_DATABASE_URL=${{ secrets.BDTOPO_DATABASE_URL }}" >> .env.local
echo "APP_FOUGERES_LITTERALIS_CREDENTIALS=${{ secrets.APP_FOUGERES_LITTERALIS_CREDENTIALS }}" >> .env.local
echo "APP_FOUGERES_ORG_ID=${{ vars.APP_FOUGERES_ORG_ID }}" >> .env.local
# Deal with JSON quotes
printf "APP_LITTERALIS_ENABLED_ORGS='%s'\n" '${{ vars.APP_LITTERALIS_ENABLED_ORGS }}' >> .env.local
- name: Run import
run: make ci_litteralis_fougeres_import BIN_PHP="php" BIN_CONSOLE="php bin/console" BIN_COMPOSER="composer"
- name: Override enabled orgs if defined by input
if: ${{ inputs.enabled_orgs }}
run: |
# Deal with JSON quotes
printf "APP_LITTERALIS_ENABLED_ORGS='%s'\n" '${{ inputs.enabled_orgs }}' >> .env.local
- name: Init organization environment variables
run: |
./tools/ci_litteralis_init_org_env_vars.py GHA_SECRETS "APP_LITTERALIS_ORG_*"
env:
APP_FOUGERES_IMPORT_APP: ${{ vars.APP_FOUGERES_IMPORT_APP }}
GHA_SECRETS: ${{ toJson(secrets) }}

- name: Run import
run: make ci_litteralis_import BIN_PHP="php" BIN_CONSOLE="php bin/console" BIN_COMPOSER="composer"

- name: Get log file path
id: logfile
Expand Down
69 changes: 0 additions & 69 deletions .github/workflows/litteralis_mel_import.yml

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/metabase_export.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
run: |
echo "DATABASE_URL=${{ secrets.METABASE_EXPORT_DATABASE_URL }}" >> .env
echo "METABASE_DATABASE_URL=${{ secrets.METABASE_EXPORT_METABASE_DATABASE_URL }}" >> .env
echo "APP_DIALOG_BASE_URL=${{ variables.METABASE_EXPORT_APP_DIALOG_BASE_URL }}" >> .env
- name: Run export
run: make ci_metabase_export BIN_PHP="php" BIN_CONSOLE="php bin/console" BIN_COMPOSER="composer"
12 changes: 3 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,11 @@ ci_eudonet_paris_import: ## Run CI steps for Eudonet Paris Import workflow
./tools/scalingodbtunnel ${EUDONET_PARIS_IMPORT_APP} --host-url --port 10000 & ./tools/wait-for-it.sh 127.0.0.1:10000
make console CMD="app:eudonet_paris:import"

ci_litteralis_mel_import: ## Run CI steps for Litteralis MEL Import workflow
ci_litteralis_import: ## Run CI steps for Litteralis Import workflow
make composer CMD="install -n --prefer-dist"
scalingo login --ssh --ssh-identity ~/.ssh/id_rsa
./tools/scalingodbtunnel ${APP_MEL_IMPORT_APP} --host-url --port 10000 & ./tools/wait-for-it.sh 127.0.0.1:10000
make console CMD="app:mel:import"

ci_litteralis_fougeres_import: ## Run CI steps for Litteralis Fougeres Import workflow
make composer CMD="install -n --prefer-dist"
scalingo login --ssh --ssh-identity ~/.ssh/id_rsa
./tools/scalingodbtunnel ${APP_FOUGERES_IMPORT_APP} --host-url --port 10000 & ./tools/wait-for-it.sh 127.0.0.1:10000
make console CMD="app:fougeres:import"
./tools/scalingodbtunnel dialog --host-url --port 10000 & ./tools/wait-for-it.sh 127.0.0.1:10000
make console CMD="app:litteralis:import"

ci_bdtopo_migrate: ## Run CI steps for BD TOPO Migrate workflow
make composer CMD="install -n --prefer-dist"
Expand Down
5 changes: 5 additions & 0 deletions assets/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ export const app = startStimulusApp(require.context(
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

// Désactive Turbo Drive par défaut, pour des raisons d'accessibilité
// On peut toujours réactiver Turbo Drive au cas par cas avec data-turbo="true"
// https://turbo.hotwired.dev/reference/drive#turbo.session.drive
Turbo.session.drive = false;

registerTurboEventHandlers();
2 changes: 2 additions & 0 deletions config/packages/framework.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ framework:
base_uri: '%env(APP_LITTERALIS_WFS_BASE_URL)%'
ign.geocoder.client:
base_uri: '%env(APP_IGN_GEOCODER_BASE_URL)%'
dialog.http.client:
base_uri: '%env(APP_DIALOG_BASE_URL)%'

when@test:
framework:
Expand Down
17 changes: 7 additions & 10 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ services:
$jopOrgId: '%env(APP_JOP_ORG_ID)%'
$featureMap: '%features%'
$cifsFilterSet: '%env(cifs_filterset:default::APP_CIFS_FILTERS)%'
$melOrgId: '%env(APP_MEL_ORG_ID)%'
$melCredentials: '%env(APP_MEL_LITTERALIS_CREDENTIALS)%' # format: 'user:pass'
$fougeresOrgId: '%env(APP_FOUGERES_ORG_ID)%'
$fougeresCredentials: '%env(APP_FOUGERES_LITTERALIS_CREDENTIALS)%' # format: 'user:pass'
$litteralisEnabledOrgs: "%env(json:default::APP_LITTERALIS_ENABLED_ORGS)%"
$litteralisCredentials: "%env(litteralis_credentials:APP_LITTERALIS_ORG_)%"
$metabaseSiteUrl: '%env(APP_METABASE_SITE_URL)%'
$metabaseSecretKey: '%env(APP_METABASE_SECRET_KEY)%'
$mediaLocation: '%env(APP_MEDIA_LOCATION)%'
Expand Down Expand Up @@ -124,12 +122,7 @@ services:
# Litteralis
# --------------

App\Infrastructure\Symfony\Command\MELImportCommand:
arguments: ['@logger']
tags:
- { name: monolog.logger, channel: litteralis_import }

App\Infrastructure\Symfony\Command\FougeresImportCommand:
App\Infrastructure\Symfony\Command\LitteralisImportCommand:
arguments: ['@logger']
tags:
- { name: monolog.logger, channel: litteralis_import }
Expand All @@ -149,6 +142,10 @@ when@test:
App\Tests\Mock\IgnGeocoderMockClient:
decorates: 'ign.geocoder.client'
decoration_inner_name: 'App\Tests\Mock\IgnGeocoderMockClient::ign.geocoder.client'
App\Tests\Mock\DiaLogMockHttpClient:
decorates: 'dialog.http.client'
decoration_inner_name: 'App\Tests\Mock\DiaLogMockHttpClient::dialog.http.client'
arguments: ['@http_kernel']
App\Infrastructure\Adapter\DateUtils:
class: App\Tests\Mock\DateUtilsMock
Psr\Log\NullLogger: ~
Expand Down
66 changes: 27 additions & 39 deletions docs/tools/litteralis.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,50 @@
# Litteralis

DiaLog dispose d'une intégration avec [Litteralis]([Litteralis](https://www.sogelink.com/solution/litteralis/)). Cette solution de gestion de réglementation de l'éditeur Sogelink est utilisée par de nombreuses collectivités notamment de plus grande taille.
DiaLog dispose d'une intégration avec [Litteralis]([Litteralis](https://www.sogelink.com/solution/litteralis/)). Cette solution de gestion de réglementation de l'éditeur Sogelink est utilisée par de nombreuses collectivités, notamment celles de plus grande taille.

## Description

L'intégration requête l'API WFS de Litteralis. Pour cela elle a besoin d'**identifiants** ("credentials" au format "user:password") configuré par la collectivité qui nous donne accès à ses données Litteralis. Elle a aussi besoin de l'**UUID** de l'organisation dans DiaLog.
L'intégration requête l'API WFS de Litteralis pour extraire les emprises que DiaLog peut intégrer.

L'intégration est "générique" au sens où elle peut être réutilisée pour plusieurs collectivités. Chaque collectivité a donc un peu de code pour faire le pont entre des variables d'environnement contenant les informations ci-dessus et l'intégration générique.
## Configuration

## Exécuter l'intégration
Les organisations à intégrer sont définies **dynamiquement** par la variable d'environnement `APP_LITTERALIS_ENABLED_ORGS`.

L'intégration peut être exécutée à l'aide de commandes Symfony spécifiques à chaque collectivité.
Par exemple :

### MEL
```bash
APP_LITTERALIS_ENABLED_ORGS='["mel", "fougeres"]'
```

**Pour l'import en prod** :
Pour chaque organisation qui y est indiquée, deux autres variables d'environnement doivent être définies : `APP_LITTERALIS_ORG_<NAME>_ID` et `APP_LITTERALIS_ORG_<NAME>_CREDENTIALS`, où `<NAME>` est à remplacer par le nom en majuscule. Exemple : `APP_LITTERALIS_ORG_MEL_ID`.

1. Récupérer le UUID de l'organisation "Métropole Européenne de Lille (MEL)" en prod. Pour cela demander à un super-admin : l'UUID est visible dans l'URL de la page de l'organisation dans l'admin.
2. Créer un fichier `.env.prod.local` vide, et y définir :
* `BDTOPO_DATABASE_URL`
* `APP_MEL_ORG_ID=ID`, où `ID` est l'UUID de la MEL que vous venez de récupérer.
* `APP_MEL_LITTERALIS_CREDENTIALS` avec les identifiants MEL au format `user:password` (les demander à un membre de l'équipe dev)
3. Ouvrir un [tunnel](./db.md#utiliser-une-db-scalingo-en-local) vers la DB de prod :
Dans GitHub Actions, les variables et secrets suivants sont configurés :

```bash
./tools/scalingodbtunnel dialog
```

Copier l'URL qui s'affiche dans le terminal.

4. Dans `.env.prod.local`, ajouter `DATABASE_URL=URL``URL` est l'URL que vous venez de copier.
5. Lancer cette commande :
```bash
make console CMD="app:mel:import --env=prod"
```
| Variable d'environnement | Variable ou Secret ? | Description |
|---|---|---|
| `APP_LITTERALIS_IMPORT_DATABASE_URL` | Secret | L'URL d'accès à la base de données par la CI (`./tools/scalingodbtunnel APP --host-url`) |
| `APP_LITTERALIS_ENABLED_ORGS` | Variable | Liste des organisations dont il faut intégrer les données Litteralis, au format array JSON |
| `APP_LITTERALIS_ORG_<NAME>_ID` | Secret | UUID de l'organisation (à définir pour chaque organisation `<NAME>` dans `APP_LITTERALIS_ENABLED_ORGS`). Peut être récupéré dans l'administration (demander à l'admin) ou dans le `<select>` du filtre Organisation de la [liste des arrêtés](https://dialog.beta.gouv.fr/regulations). |
| `APP_LITTERALIS_ORG_<NAME>_CREDENTIALS` | Secret | Identifiants d'accès à l'API Litteralis de l'organisation, au format `username:password` (à définir pour chaque organisation `<NAME>` dans `APP_LITTERALIS_ENABLED_ORGS`). es identifiants sont à activer dans Litteralis par la collectivité qui nous donne accès à ses données. |
| `GH_SCALINGO_SSH_PRIVATE_KEY` | Secret | Clé SSH privée permettant l'accès à Scalingo par la CI |

L'exécution prendra plusieurs minutes. Les logs d'exécution seront ajoutés au dossier `logs/litteralis/`. En cas d'exception la commande échouera. Un rapport final "pretty print" est affiché.
## Utilisation

**Pour le dev local** : remplir `.env.local` au lieu de `.env.prod`, sauter les étapes 3 et 4 (utiliser votre DB locale), et ne pas inclure le flag `--env=prod`.
### Avec GitHub Actions

## Déploiement périodique automatique
L'import est exécuté **automatiquement** tous les lundis à l'aide d'un [workflow](../../.github/workflows/litteralis_import.yml) GitHub Actions.

### MEL
L'import peut aussi être exécuté **manuellement** à l'aide du bouton "Workflow dispatch". Vous pouvez alors n'exécuter l'import que pour certaines collectivités en précisant le paramètre `enabled_orgs`, qui remplacera temporairement la variable `APP_LITTERALIS_ENABLED_ORGS` configurée sur le repo.

Les données la MEL sont automatiquement intégrées en production tous les lundis à 16h00.
### En local

Cette automatisation est réalisée au moyen de [GitHub Actions](./github_actions.md) via le workflow [`litteralis_mel_import.yml`](../../.github/workflows/litteralis_mel_import.yml).
Pour le développement, l'import peut être exécuté en local en appelant la commande Symfony :

La configuration passe par diverses variables d'environnement listées ci-dessous :
```bash
make console CMD="app:litteralis:import"
```

| Variable d'environnement | Configuration | Description |
|---|---|---|
| `APP_MEL_IMPORT_APP` | [Variable](https://docs.github.com/fr/actions/learn-github-actions/variables) au sens GitHub Actions | L'application Scalingo cible (par exemple `dialog` pour la production) |
| `APP_MEL_LITTERALIS_CREDENTIALS` | [Secret](https://docs.github.com/fr/actions/security-guides/using-secrets-in-github-actions) au sens GitHub Actions | Les identifiants d'accès à l'API Litteralis de la MEL |
| `APP_MEL_IMPORT_DATABASE_URL` | Secret | L'URL d'accès à la base de données par la CI (`./tools/scalingodbtunnel APP --host-url`) |
| `APP_MEL_ORG_ID` | Variable | Le UUID de l'organisation "Métropole Européenne de Lille" dans l'environnement défini par `APP_MEL_IMPORT_APP` |
| `GH_SCALINGO_SSH_PRIVATE_KEY` | Secret | Clé SSH privée permettant l'accès à Scalingo par la CI |
Cela lira les variables `APP_LITTERALIS_ENABLED_ORGS` et `APP_LITTERALIS_ORG_*` dans votre `.env.local`.

## Références

Expand Down
1 change: 1 addition & 0 deletions docs/tools/metabase.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ La configuration de la GitHub Action passe par diverses variables d'environnemen
| `METABASE_MIGRATIONS_METABASE_DATABASE_URL` | [Secret](https://docs.github.com/fr/actions/security-guides/using-secrets-in-github-actions) au sens GitHub Actions | L'URL d'accès à la base de données Metabase par la CI, afin d'exécuter les migrations (`./tools/scalingodbtunnel dialog-metabase --host-url --port 10001`) |
| `METABASE_EXPORT_DATABASE_URL` | [Secret](https://docs.github.com/fr/actions/security-guides/using-secrets-in-github-actions) au sens GitHub Actions | L'URL d'accès à la base de données applicative par la CI (`./tools/scalingodbtunnel dialog --host-url --port 10000`) |
| `METABASE_EXPORT_METABASE_DATABASE_URL` | Secret | L'URL d'accès à la base de données Metabase par la CI (`./tools/scalingodbtunnel dialog-metabase --host-url --port 10001`) |
| `METABASE_EXPORT_APP_DIALOG_BASE_URL` | Variable | L'URL publique de DiaLog (pour la requête des exports tels que CIFS) |
| `GH_SCALINGO_SSH_PRIVATE_KEY` | Secret | Clé SSH privée permettant l'accès à Scalingo par la CI |
10 changes: 10 additions & 0 deletions src/Application/Cifs/CifsExportClientInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace App\Application\Cifs;

interface CifsExportClientInterface
{
public function getIncidentsCount(): int;
}
40 changes: 40 additions & 0 deletions src/Application/Litteralis/DTO/LitteralisCredentials.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace App\Application\Litteralis\DTO;

final class LitteralisCredentials
{
private array $credentials;

public function __construct()
{
$this->credentials = [];
}

public function add(string $name, string $orgId, string $credentials): self
{
$this->credentials[$name] = ['orgId' => $orgId, 'credentials' => $credentials];

return $this;
}

public function getOrgId(string $name): ?string
{
if (\array_key_exists($name, $this->credentials)) {
return $this->credentials[$name]['orgId'];
}

return null;
}

public function getCredentials(string $name): ?string
{
if (\array_key_exists($name, $this->credentials)) {
return $this->credentials[$name]['credentials'];
}

return null;
}
}
Loading

0 comments on commit 3114647

Please sign in to comment.