Formats d'archive — import & export
Plusieurs fonctions d'Open ENT produisent ou consomment des archives .zip. Elles n'ont ni le
même contenu ni le même usage : cette page décrit ce qu'il y a dans chaque archive, qui la
produit, qui sait la relire et les règles de validation appliquées à l'import.
Vue d'ensemble
| Archive | Produite par | Relue par | Format |
|---|---|---|---|
| Archive de données personnelles | Export « Mes données », Sauvegarde admin, Reprise, Duplication | Import « Mes données », Restauration admin | .zip — 1 dossier racine + Manifest.json + 1 dossier par application |
| Lot d'export d'établissement | Sauvegarde admin, onglet Établissement (super-admin) | Aucune (chaque sous-dossier se réimporte seul, pas le lot) | .zip — plusieurs dossiers de comptes, chacun au format d'une archive personnelle |
| Dossier de l'espace documentaire | Poste de l'utilisateur (n'importe quel zip) | POST /workspace/zip | .zip quelconque — l'arborescence est reproduite telle quelle |
| Lot d'import CSV de comptes | Établissement / exploitant | Feeder (dépôt sur disque) | .zip contenant des .csv, nom du zip porteur de l'UAI |
| Emploi du temps UDT | Logiciel UDT (1er degré / Pronote) | Feeder timetable | .zip contenant les XML UDT |
| Emploi du temps EDT | Logiciel EDT | Feeder timetable | .xml (pas d'archive) |
| Alimentation AAF | Rectorat (DRASI) | Feeder AAF | .xml (pas d'archive) — voir Import AAF |
| Export ELIOT | Feeder (exporter ELIOT) | Système tiers, acheminé en WebDAV | .zip de fichiers d'export annuaire |
| Paquet d'échange inter-ENT (OEIP) | Module interoperability (à développer) | Un autre ENT, quel qu'en soit l'éditeur | .oeip — voir OEIP |
Le reste de la page détaille la première ligne (le format le plus utilisé, celui des exports utilisateur), puis résume les autres.
Tous les formats décrits ici sont internes : ils servent à restaurer ou à alimenter cette plateforme, et supposent qu'Open ENT se trouve des deux côtés. Ils ne conviennent pas à un échange vers un autre ENT — notamment parce que les noms de dossiers y sont des libellés traduits et que la signature d'archive exige la même paire de clés à l'émission et à la réception.
Pour transporter des données vers un autre ENT, le format est OEIP. Il réutilise la tuyauterie d'export et d'import décrite ici (son niveau Native embarque la charge utile d'archive telle quelle), mais y ajoute un modèle sémantique, des identifiants globaux, des schémas versionnés et une intégrité vérifiable sans clé.
L'archive de données personnelles
C'est le format pivot d'Open ENT : le même .zip sert à l'export RGPD de l'usager, à la
sauvegarde d'un compte par un administrateur, à la duplication d'une ressource et à la reprise de
données depuis une ancienne plateforme.
Quatre fonctions s'appuient dessus :
- Mes données — l'usager exporte / réimporte ses contenus (RGPD).
- Sauvegarde & restauration — l'administrateur local sauvegarde son propre compte.
- Duplication (
POST /archive/duplicate) — export puis réimport immédiat d'une seule ressource, sans passer par un fichier téléchargé. - Reprise — export planifié des comptes d'une ancienne plateforme, rejoué à l'import sur la nouvelle.
Périmètre : un compte à la fois, jamais une requête « application entière »
Le socle n'a aucune notion d'export applicatif global : chaque service d'export interroge sa
base en filtrant systématiquement sur owner / author = un compte (plus, en option, les
ressources partagées avec ses groupes). Il n'existe aucune requête « toutes les ressources du
module, tous comptes confondus » dans la chaîne d'export — c'est une contrainte du socle, pas un
choix d'interface.
Sauvegarder un établissement ne contourne donc pas cette contrainte : la fonction répète l'export personnel standard pour chaque compte d'un groupe choisi (une classe, un groupe de profil…) et assemble les archives individuelles obtenues en un lot. Ce n'est ni un export « application entière », ni un export « établissement » au sens d'une requête unique — c'est un export par compte, automatisé et regroupé.
| Fonction | Périmètre réel | Qui peut la lancer |
|---|---|---|
POST /archive/export — Mes données, onglet Exporter ; Sauvegarde admin, onglet Exporter | Le compte connecté, applications au choix | Tout usager (workflow archive.export), y compris l'ADML pour son propre compte |
POST /archive/export/user | Un compte désigné, avec toutes les applications déclarées dans publicConf.apps | Super-administrateur, MFA obligatoire |
POST /archive/export/structure | Tous les comptes d'un groupe d'un établissement, un export par compte assemblé en un lot | Super-administrateur, MFA obligatoire |
GET /archive/export/admin/list | Supervision : liste les exports en cours / prêts de tous les comptes — lecture seule | Super-administrateur (l'archive reste téléchargeable par son seul propriétaire) |
| Reprise (tâche planifiée) | Tous les comptes d'une ancienne plateforme, mais une archive par compte | Exploitant (configuration reprise) |
POST /archive/duplicate | Une seule ressource | Usager, sur ses propres ressources |
Si un export de tout un module est vraiment nécessaire (migration, audit, réversibilité
contractuelle) — c'est-à-dire l'intégralité des ressources d'une application indépendamment des
comptes qui les possèdent — la sauvegarde d'établissement ne le fournit pas non plus : elle reste
bornée aux comptes d'un groupe. Seule une extraction base de données côté exploitation (dump de
la collection MongoDB ou du schéma PostgreSQL du module, plus les fichiers du storage) donne
l'intégralité d'un module, mais le résultat n'est pas réimportable par /archive/import.
Sauvegarde d'un établissement (lot)
Concerne :Super-administrateurPOST /archive/export/structure prend un groupId (une classe, un groupe de profil, un groupe
manuel…) et la liste des applications à exporter. Pour chaque compte du groupe :
- Résolution des membres et de leurs groupes (Neo4j), pour reproduire fidèlement le périmètre « ressources partagées » qu'aurait un export personnel de ce compte.
- Publication du même message
user.repository/ actionexportqu'un export personnel (POST /archive/export), avec un identifiant synthétiquestruct-<batchId>_<userId>et un chemin de destination propre au lot — chaque module applicatif exporte donc ce compte exactement comme s'il répondait à un export personnel, sans le savoir. - Une fois toutes les applications répondues pour un compte : écriture de son
Manifest.jsonet de sa signature (si une clé est configurée), exactement comme un export personnel — ce sous-dossier est donc réimportable seul, en le re-zippant, via/archive/import. - Une fois tous les comptes du groupe traités : écriture d'un
Batch-Manifest.jsonau niveau du lot (structure, groupe, comptes, statut par compte) et compression de l'ensemble.
<batchId>.zip
└── <batchId>/
├── Batch-Manifest.json ← rapport du lot : comptes, statut, applications
├── Rousseau Nadia_f1a2b3c4-…/ ← 1 sous-dossier par compte du groupe
│ ├── Manifest.json ← identique à un export personnel
│ ├── archive.signature
│ ├── Blog/
│ └── Espace documentaire/
└── Martin Amelie_9c7d2e1f-…/
├── Manifest.json
├── archive.signature
└── …
Contrairement aux autres archives de cette page, le .zip du lot n'a pas de dossier racine
unique avec un Manifest.json à sa racine — il contient plusieurs dossiers de comptes côte à
côte. /archive/import le refuse donc tel quel (Archive file not recognized) : c'est
/archive/import/structure/* (ci-dessous) qui sait le lire.
Restauration groupée d'un lot
Concerne :Super-administrateurRestaurer un lot revient à rejouer, compte par compte, l'import personnel standard — mais à
destination du compte d'origine, et non de la personne connectée. Cette dissociation existe déjà
dans le socle : ImportService.importFromFile(fileName, userId, …) prend le compte cible en
paramètre, et c'est par là que passe aussi la reprise depuis une autre plate-forme. La restauration
groupée n'invente donc pas un second mécanisme d'import, elle réutilise celui-là.
| Route | Rôle |
|---|---|
POST /archive/import/structure/upload | dépose le .zip du lot, renvoie un restoreId |
GET /archive/import/structure/:id/analyze | décompresse, lit le Batch-Manifest.json, rend un verdict par compte |
POST /archive/import/structure/:id/launch | lance la restauration, refusée si l'analyse n'a pas tout validé |
GET /archive/import/structure/:id/status | avancement et résultat par compte |
DELETE /archive/import/structure/:id | supprime l'espace de travail |
GET /archive/import/structure/admin/list | vue plateforme de toutes les restaurations suivies |
Toutes sont réservées au super-administrateur (SuperAdminFilter + @MfaProtected), là où
l'export d'un lot s'ouvre aussi aux comptes ADMIN_COLLECTIVITE : lire les données d'un
établissement et écrire dans les comptes de ses usagers ne sont pas le même pouvoir.
Les trois contrôles de destinataire. Se tromper de compte verserait les documents d'une personne chez une autre : chaque dossier est donc validé trois fois, par des sources indépendantes, et un seul échec fait refuser le lot entier.
- Le
Batch-Manifest.jsondéclare unuserIdpour cefolder. - Le nom du dossier se termine par
_<userId>— l'export le suffixe ainsi pour lever les homonymies, ce qui en fait une seconde source qu'il faudrait falsifier de concert. - Le nœud
Userexiste encore et ne porte pas dedeleteDate.
Déroulé d'un compte. Son dossier est déplacé (et non copié — le lot décompressé est un espace
de travail jetable, et recopier une classe entière doublerait l'occupation disque) dans un dossier
d'apprêt, lequel est zippé sous <importPath>/<millis>_<userId> : le zip contient alors un unique
dossier racine, seul format que analyzeArchive accepte. importFromFile prend le relais.
Séquentiel, et borné dans le temps. Un seul compte à la fois : un import mobilise tous les
modules de l'ENT. Et comme la chaîne n'avance que sur l'événement de fin d'import, un module muet
figerait tout le lot — un minuteur par compte (structure-import-account-timeout, 30 min par
défaut) marque le compte en erreur et passe au suivant.
L'import restant additif, rejouer un lot duplique les contenus au lieu de les remplacer.
Un compte du groupe peut lancer son propre export personnel (« Mes données ») pendant qu'il est inclus dans un lot : le suivi du lot est entièrement séparé de celui des exports personnels, aucune collision ni verrou partagé.
Un lot dont une application ne répondrait jamais (module indisponible) ne reste pas bloqué
indéfiniment : structureExportPurgePeriod/structureExportMaxAge purgent les lots restés
« en cours » au-delà du délai configuré, sur le même principe que periodicUserClear pour les
exports personnels.
Les écrans
Côté usager — /archive (Mes données)
L'usager coche les applications à exporter (ou Tous) puis Télécharger mes données ; le bouton reste désactivé tant que rien n'est sélectionné. L'onglet Importer sert à redéposer une archive précédemment exportée. Le bandeau rappelle explicitement que les applications autres que l'Espace documentaire et le Casier sont exportées au format brut JSON — ce sont les fichiers sans extension décrits plus bas.
Côté administration — /admin/applications/backup
Même moteur, présentation différente : sélection des modules, Sauvegarder mon compte, puis un historique des exports rafraîchi en temps réel (demandeur, statut, téléchargement, suppression). L'historique est cloisonné — un ADML voit les demandes de ses établissements, un super-administrateur voit tout — et seul le demandeur peut télécharger son archive. Un super-administrateur dispose en plus de la supervision plateforme : tous les exports en cours, tous comptes confondus, en lecture seule.
L'onglet Restaurer dépose une archive .zip et enchaîne upload → analyse → import. La
restauration s'ajoute au contenu existant, elle ne l'écrase pas.
Un super-administrateur dispose d'un troisième onglet, Établissement : un tableau des
groupes de l'établissement sélectionné, avec effectif et volume estimé par groupe
(UserBook.storage), des cases à cocher (un lot = les groupes cochés) et un total dédoublonné
quand un compte appartient à plusieurs groupes cochés. Voir
Sauvegarde d'un établissement (lot) ci-dessus pour le
format produit.
/archive et /admin/applications/backup appellent les mêmes routes entcore. Le dashboard y
ajoute un suivi de jobs, la purge des exports bloqués et la supervision plateforme ; il ne change
ni le format de l'archive, ni le périmètre de l'export.
Nom et emplacement du fichier
L'identifiant d'export est <horodatage>_<userId> ; l'archive téléchargée s'appelle donc
1730812345678_f1a2b3c4-….zip. Elle est produite dans export-path, stockée dans le
storage (disque ou S3) puis supprimée après un téléchargement réussi — et purgée
périodiquement (purgeArchive, deleteDelay) pour les archives jamais récupérées.
Arborescence
Le zip contient un unique dossier racine (l'identifiant d'export). L'import refuse toute archive qui n'a pas exactement cette forme.
1730812345678_f1a2b3c4-….zip
└── 1730812345678_f1a2b3c4-…/
├── Manifest.json ← inventaire des applications exportées
├── archive.signature ← empreintes RSA (si une clé est configurée)
├── Blog/
│ ├── Mon premier billet ← 1 fichier par ressource (JSON, sans extension)
│ ├── Journal de la classe
│ └── Documents/ ← pièces jointes référencées par ces ressources
│ └── photo_5f3e….jpg
├── Espace documentaire/
│ ├── Espace documentaire ← métadonnées JSON de tous les documents
│ ├── Documents personnels/ ← fichiers réels, arborescence de l'usager reproduite
│ ├── Documents partages/
│ ├── Documents ajoutes dans les applis/
│ └── Corbeille/
└── Formulaire/
├── form ← 1 fichier par table SQL
├── question
└── Documents/
Le dossier porte le libellé traduit de l'application, accents retirés (Espace documentaire,
Cahier de textes…). La correspondance « clé technique → nom de dossier » est justement le rôle du
Manifest.json : ne pas se fier au nom seul pour rattacher un dossier à une application.
Manifest.json
Inventaire des applications réellement exportées, avec le nom du dossier correspondant et la version du module au moment de l'export :
{
"blog": { "folder": "Blog", "version": "6.14.9" },
"workspace": { "folder": "Espace documentaire", "version": "6.14.9" },
"formulaire": { "folder": "Formulaire" }
}
- La clé est le préfixe de route de l'application (
blog,workspace,formulaire…). versionest facultative : elle est omise si la plateforme ne connaît pas la version du module. Une archive sans version reste importable (voir contrôle de version).- Les archives anciennes peuvent porter une clé complète (
org.entcore.blog) et une valeur directement égale à la version : l'import accepte les deux écritures.
archive.signature
Présent uniquement si la plateforme est configurée avec une clé RSA (archive-private-key). Il
associe à chaque entrée du dossier racine son empreinte signée :
{
"Manifest.json": "MEUCIQD…",
"Blog": "MEQCIB…",
"Espace documentaire": "MEYCIQC…"
}
À l'import, chaque dossier listé est vérifié contre cette signature ; une entrée absente de la signature ou dont l'empreinte ne correspond pas fait échouer l'import et supprime l'archive.
Contenu d'un dossier d'application
Le format dépend de la base de données de l'application — c'est le socle entcore qui l'écrit, pas
chaque module :
| Type d'application | Contenu du dossier |
|---|---|
| Applications MongoDB (blog, pad, mur collaboratif, carte mentale…) | Un fichier par ressource, sans extension, nommé d'après le titre de la ressource (caractères interdits remplacés, suffixé par l'identifiant en cas d'homonymie). Le contenu est le document Mongo brut en JSON. |
| Applications PostgreSQL (formulaire, messagerie, exercices…) | Un fichier par table, nommé d'après la table, contenant { "fields": [...], "results": [[...]] } — l'ordre des cellules de chaque ligne suit celui de fields. |
| Espace documentaire | Les fichiers réels de l'usager, rangés dans quatre sous-dossiers (Documents personnels, Documents partages, Documents ajoutes dans les applis, Corbeille) qui reproduisent son arborescence, plus un fichier de métadonnées JSON portant le nom de l'application. |
| Toutes (si documents demandés) | Un sous-dossier Documents/ contenant les pièces jointes citées par les ressources. Chaque fichier est renommé <nom>_<identifiant>.<extension> pour éviter les collisions et permettre le ré-attachement à l'import. |
Options de l'export
POST /archive/export accepte trois réglages qui changent le contenu de l'archive :
| Champ | Défaut | Effet |
|---|---|---|
apps | — | Liste des applications à exporter (préfixes de route). Seules celles-ci apparaissent dans le Manifest.json. |
exportDocuments | true | À false, les pièces jointes ne sont pas embarquées : pas de dossier Documents/, et l'espace documentaire ne contient que ses métadonnées, accompagnées d'un marqueur skipDocs qui indique à l'import de ne pas chercher les fichiers. |
exportSharedResources | true | À false, seules les ressources dont l'usager est auteur ou propriétaire sont exportées ; les ressources simplement partagées avec lui sont écartées. |
Un export est exclusif par compte : tant qu'un export est en cours ou téléchargeable, une
nouvelle demande est refusée (export.exists).
Ce que l'import attend
Contrôles appliqués à l'import
L'analyse (GET /archive/import/analyze/:importId) applique, dans l'ordre :
- Décompression — l'archive doit contenir exactement un dossier racine, sinon
Archive file not recognized. Manifest.jsonobligatoire à la racine de ce dossier, sinonArchive file not recognized - Missing 'Manifest.json'.- Signature — si une clé de vérification est configurée,
archive.signaturedoit être présent et cohérent avec le contenu. Avecforce-encryption: true, une archive non signée est rejetée ; sinon elle passe. - Droits — une application n'est proposée à l'import que si l'utilisateur connecté possède le
workflow déclaré dans
publicConf.apps. Une application absente de ce paramétrage n'est jamais restaurée, même présente dans l'archive. - Version minimale — si
minimum-import-versiondéclare une version pour l'application et que leManifest.jsonporte une version antérieure, l'application est ignorée. Une archive sans version échappe à ce contrôle (rétro-compatibilité des anciens exports). - Quota — l'analyse renvoie la taille de chaque dossier et le quota disponible, pour que l'interface prévienne avant de lancer l'import.
L'analyse renvoie donc la liste des applications réellement restaurables, avec leur dossier et
leur taille — le lancement (POST /archive/import/:importId/launch) ne porte que sur celles-là.
Comportement de l'import
- L'import est additif : rien n'est écrasé ni supprimé dans le compte cible.
- Les ressources reçoivent de nouveaux identifiants, et les références internes (liens, pièces jointes) sont réécrites en conséquence.
- Une ressource déjà présente est importée en doublon, avec le suffixe
— Copiesur son titre. - Tout est rattaché au compte qui lance l'import : entcore n'expose pas d'import « vers un utilisateur cible ».
- Un rapport par application est renvoyé (nombre de ressources, de doublons, d'erreurs).
Erreurs fréquentes
| Message | Cause | Correctif |
|---|---|---|
Archive file not recognized | Le zip a été recréé en zippant le contenu du dossier racine au lieu du dossier lui-même | Rezipper en incluant le dossier racine |
Archive file not recognized - Missing 'Manifest.json' | Archive tronquée, ou zip d'autre provenance | Repartir de l'archive d'export d'origine |
Archive signature does not list the folder … / does not match the signature | Archive modifiée après export, ou exportée sur une plateforme avec une autre clé | Réimporter l'archive intacte, sur une plateforme partageant la clé |
| Application absente de la liste après analyse | Workflow manquant, application non déclarée dans publicConf.apps, ou version inférieure à minimum-import-version | Vérifier les droits du compte importateur et le paramétrage du module archive |
export.exists au lancement d'un export | Un export du même compte est déjà en cours ou en attente de téléchargement | Télécharger ou supprimer l'export en cours ; le sweep periodicUserClear purge les exports bloqués |
Routes
| Route | Usage |
|---|---|
POST /archive/export | Lance un export pour le compte connecté |
GET /archive/export/verify/:exportId | Suit l'état de l'export |
GET /archive/export/:exportId | Télécharge l'archive (et la supprime ensuite) |
POST /archive/import/upload | Dépose une archive à importer |
GET /archive/import/analyze/:importId | Analyse l'archive et liste les applications restaurables |
POST /archive/import/:importId/launch | Lance l'import sur les applications retenues |
GET /archive/import/delete/:importId | Abandonne l'import et supprime l'archive déposée |
POST /archive/duplicate | Duplique une ressource (export + import enchaînés en interne) |
POST /archive/export/structure | Lance un lot d'export pour tous les comptes d'un groupe (super-admin, MFA) |
GET /archive/export/structure/:batchId/status | État du lot (comptes traités, en erreur) (super-admin, MFA) |
GET /archive/export/structure/:batchId | Télécharge l'archive du lot, une fois terminé (super-admin, MFA) |
DELETE /archive/export/structure/:batchId | Supprime le lot (super-admin, MFA) |
GET /archive/export/structure/admin/list | Supervision : tous les lots suivis (super-admin, MFA) |
Paramétrage du module archive
| Clé | Rôle |
|---|---|
export-path / import-path | Répertoires de travail des archives |
archive-private-key | Clé RSA de signature / vérification des archives |
force-encryption | Refuse les archives non signées (production) |
publicConf.apps | Applications restaurables : préfixe de route → workflow requis (restauration uniquement — n'affecte pas les exports, y compris les lots d'établissement) |
minimum-import-version | Version minimale acceptée par application |
purgeArchive, deleteDelay, maxFileAge | Purge planifiée des archives non téléchargées |
periodicUserClear, userClearDelay | Purge des exports personnels restés bloqués « en cours » |
max-users-per-batch | Taille maximale d'un lot d'établissement (rejeté au lancement si le groupe est plus grand) |
structureExportPurgePeriod, structureExportMaxAge | Purge des lots d'établissement restés bloqués |
reprise | Paramètres de la reprise depuis une ancienne plateforme |
Les autres archives de la plateforme
Import d'un dossier dans l'espace documentaire
POST /workspace/zip accepte n'importe quelle archive zip : l'arborescence est reproduite
telle quelle dans l'espace documentaire de l'usager. Il n'y a ni manifeste ni signature.
- L'encodage des noms de fichiers est détecté automatiquement (UTF-8 puis les encodages déclarés par la plateforme) — utile pour les zips produits sous Windows.
- Chaque fichier passe par la validation de type et l'antivirus ; les fichiers refusés sont remontés dans le rapport d'import sans bloquer le reste.
- Le quota de l'usager s'applique.
Voir Espace documentaire.
Lot d'import CSV de comptes
Le feeder scrute un répertoire de dépôt et traite les .zip par ordre alphabétique.
- Le nom du zip doit contenir l'UAI de l'établissement (7 chiffres + 1 lettre majuscule, par
exemple
0123456A_Lycee-Exemple.zip) : sans UAI, le lot est rejeté. - L'archive contient des fichiers
.csvdont le nom porte le profil (élèves, enseignants, personnels, responsables…) selon les motifs déclarés dans la configuration du feeder. - Un lot sans aucun
.csvest ignoré.
Le format des colonnes est décrit dans Import CSV.
Emplois du temps
- UDT — archive
.zipdéposée dans le répertoire d'import ; elle est décompressée puis les XML UDT sont traités. - EDT — fichiers
.xmldéposés directement, sans archive.
Export ELIOT
Quand le feeder est configuré avec l'exporteur ELIOT, l'export annuaire est zippé puis
acheminé vers la destination configurée (WebDAV). C'est un flux sortant d'exploitation, sans
rapport avec les archives utilisateur.
Alimentation AAF
L'AAF n'est pas une archive : ce sont des fichiers XML fournis par le rectorat et intégrés périodiquement. Voir Import AAF.
Bonnes pratiques
- Ne jamais modifier une archive exportée avant de la réimporter : le zip doit conserver son
dossier racine, son
Manifest.jsonet, le cas échéant, sa signature. - Télécharger rapidement un export : l'archive est supprimée après téléchargement et purgée automatiquement au bout du délai configuré.
- Importer avec le bon compte : les contenus atterrissent toujours dans le compte qui lance l'import, et seules les applications dont ce compte a le workflow sont restaurées.
- Réimporter avec prudence : l'import étant additif, un import répété crée des doublons
(suffixés
— Copie) plutôt que de mettre à jour l'existant. - Conserver la clé de signature entre deux plateformes qui doivent s'échanger des archives.
- Choisir des lots de taille raisonnable pour une sauvegarde d'établissement : l'estimation par groupe (effectif, volume) est là pour ça — un groupe trop volumineux ralentit d'autant le lot et l'espace disque qu'il occupe pendant l'assemblage.
- Ne pas réimporter un lot tel quel : extraire et re-zipper le sous-dossier du compte visé
avant de le passer à
/archive/import.
Voir aussi
- Mes données — export / import par l'usager (RGPD)
- Sauvegarde & restauration — sauvegarde d'un compte par un administrateur
- Import CSV et Import AAF — alimentation de l'annuaire
- Feeder — alimentation et exports d'annuaire