Declarative Infrastructure as Code (IaC) for Odoo via XML-RPC
Project description
Odoo Online Deploy (ood) — Infrastructure as Code (IaC)
Ce package Python, nommé Odoo Online Deploy (ood), implémente un moteur de configuration et de personnalisation Infrastructure as Code (IaC) inspiré du fonctionnement de Terraform pour n'importe quelle instance d'ERP Odoo (y compris les instances Odoo Online, On-Premise ou Odoo.sh).
Grâce à ce moteur, vous pouvez déclarer la structure de votre base de données, vos règles de sécurité, vos vues utilisateur, vos automatisations et vos crons dans un fichier déclaratif YAML unique (main.ood), puis les appliquer de façon déterministe, ordonnée et idempotente via XML-RPC.
🏗️ Architecture du Système
Le moteur IaC orchestre le cycle de vie de vos personnalisations à travers trois fichiers clés :
[ main.ood ] [ variables.ood ] [ ood.oodstate ]
(Configurations) (Paramètres/Secrets) (État local JSON)
│ │ │
└─────────────┬───────┴─────────────────────┘
▼
[ Moteur CLI ood ]
│
▼
{ Compilateur de Diff }
│ (Analyse comparative)
▼
[ Arbre d'actions (Diff) ] ──► + create, ~ update, - destroy
│ (Approbation utilisateur)
▼
[ Handlers XML-RPC ]
│ (Modifications ordonnées)
▼
[( Instance Odoo 18 / 19 )]
│
▼ (Enregistrement des IDs Odoo)
[ ood.oodstate ]
main.ood: Fichier YAML décrivant l'ensemble de votre infrastructure et de vos personnalisations (applications, champs, règles de sécurité, automatisations).variables.ood: Fichier contenant les variables d'environnement locales et les secrets de connexion.ood.oodstate: Fichier d'état local auto-généré (analogue à un fichierterraform.tfstate) qui conserve la trace des identifiants uniques (IDs) des ressources créées pour assurer l'idempotence et les suppressions propres.
⚙️ Installation
1. Prérequis
Assurez-vous de disposer de Python >= 3.8.
2. Installation depuis PyPI (Production)
Pour installer l'outil globalement ou au sein de votre projet :
pip install ood-cli
3. Installation locale pour le développement (Mode Éditable)
Si vous modifiez directement le code source du projet :
# Créez et activez un environnement virtuel (optionnel mais fortement recommandé)
python3 -m venv venv
source venv/bin/activate
# Installation en mode éditable
pip install -e .
Cette commande installe les dépendances requises et enregistre un point d'entrée global dans votre terminal. Vous pouvez désormais lancer le moteur en saisissant la commande :
ood --help
🚀 Workflow d'Exécution (Terraform-like)
Étape 1 : Initialisation (ood init)
Initialise le répertoire de travail, teste la validité des paramètres de connexion à l'instance Odoo cible et génère un fichier ood.oodstate vide s'il n'existe pas.
ood init
Étape 2 : Comparaison et Prévisualisation (ood plan)
Compare les déclarations du fichier main.ood avec l'état enregistré dans ood.oodstate. Le moteur compile un arbre de différences (diff) ordonné selon les dépendances et affiche un aperçu coloré des actions à effectuer :
+ create: Ressources déclarées dans la configuration mais absentes de l'état.~ update: Ressources modifiées (par exemple, code d'un cron ou d'une action serveur mis à jour).- destroy: Ressources supprimées du fichiermain.oodmais toujours présentes dans l'état (le moteur les désinstalle proprement d'Odoo).
ood plan
Étape 3 : Application des Changements (ood apply)
Valide le plan, demande confirmation à l'utilisateur (sauf si --auto-approve est fourni), applique les modifications dans l'ordre strict des dépendances et met à jour le fichier d'état avec les identifiants réels renvoyés par la base de données.
ood apply
# ou pour une exécution automatisée (ex: CI/CD)
ood apply --auto-approve
Étape 4 : Destruction Complète (ood destroy)
Wipe et nettoie l'intégralité des personnalisations créées en les supprimant proprement en base d'Odoo en ordre inverse de dépendance, afin de restituer une instance parfaitement propre.
ood destroy
# ou sans confirmation manuelle
ood destroy --auto-approve
📝 Guide de la Gestion des Variables et Secrets (variables.ood)
Le fichier variables.ood centralise les secrets et les valeurs d'interpolation dynamique de votre projet. Les valeurs y sont injectées au sein de vos configurations via la syntaxe ${MA_VARIABLE}.
1. Variables globales et modulaires
- Fichier global : Un fichier
variables.oodà la racine de votre workspace définit les paramètres généraux (configurations de connexion, etc.). - Fichiers locaux : Lorsque vous découpez vos configurations dans des sous-dossiers (voir section
includeci-dessous), vous pouvez placer un fichiervariables.oodlocal au sein de chaque dossier fonctionnel (ex :modules/sales/variables.ood). Le moteur IaC compile automatiquement l'ensemble de ces fichiers pour alimenter l'interpolation.
2. Sécurité contre les collisions de noms (Validation stricte)
Pour éviter qu'une variable ne soit écrasée par inadvertance, le moteur effectue une validation de sécurité stricte lors du chargement. Si une même clé de variable est déclarée dans plus d'un fichier variables.ood, l'initialisation s'interrompt immédiatement en levant une erreur descriptive indiquant les chemins exacts en conflit :
Error: Failed to load and compile configuration: La variable 'MON_SECRET' est déclarée plusieurs fois : dans 'variables.ood' et dans 'modules/sales/variables.ood'.
Exemple standard :
# variables.ood
ODOO_URL: "http://localhost:8069"
ODOO_DB: "odoo"
ODOO_LOGIN: "admin"
ODOO_PASSWORD: "mon_api_key_ou_password"
ODOO_VERSION: "19.0" # Permet d'adapter les syntaxes XML et sécurité (18.0 ou 19.0)
🛠️ Spécifications du fichier main.ood
Le fichier main.ood est structuré autour de trois sections principales :
connection: Référence les paramètres de connexion à l'instance Odoo (généralement interpolés depuisvariables.ood).include(Optionnel) : Une liste de motifs de chemins (glob patterns) pour importer des sous-fichiers de configuration.oodde façon modulaire et ordonnée.resources: Une liste d'objets YAML définissant les composants à provisionner directement dans ce fichier.
📁 Découpage Modulaire via la Balise include
Pour des projets complexes, vous pouvez éclater vos ressources dans des sous-fichiers configurables. Les chemins sont résolus relativement au dossier du fichier déclarant l'inclusion. Le moteur supporte la recherche par jokers (wildcards globbing) et les inclusions récursives.
# main.ood
connection:
url: "${ODOO_URL}"
db: "${ODOO_DB}"
username: "${ODOO_LOGIN}"
password: "${ODOO_PASSWORD}"
odoo_version: "${ODOO_VERSION}"
include:
- "modules/security/*.ood"
- "modules/sales/**/*.ood"
resources:
- type: app
name: base
Les ressources importées sont compilées et insérées avant les ressources déclarées localement. De plus, toutes les variables définies dans les fichiers variables.ood locaux aux dossiers importés sont compilées et appliquées à l'ensemble du projet.
📋 Types de Ressources Supportés (Règles syntaxiques)
Voici la liste exhaustive des types de ressources configurables, avec leur ordre de déploiement topologique :
| Ordre | Type (type) |
Modèle Odoo cible | Description |
|---|---|---|---|
| 1 | app |
ir.module.module |
Installe une application ou un module du catalogue natif. |
| 2 | privilege |
res.groups.privilege |
Définit une catégorie de privilège (spécifique Odoo 19). |
| 3 | group |
res.groups |
Gère les groupes de sécurité, l'héritage (implied) et les privilèges. |
| 4 | model |
ir.model |
Crée un nouveau modèle de données personnalisé (avec auto-correction du préfixe x_ et gestion des mixins comme Chatter ou Activités via inherit). |
| 5 | field |
ir.model.fields |
Crée des champs personnalisés de type standard (char, float, selection, many2one...) ou calculés (compute). |
| 6 | acl |
ir.model.access |
Renseigne les droits de CRUD au niveau du modèle d'objet pour un groupe donné. |
| 7 | rule |
ir.rule |
Applique des filtres de sécurité ligne par ligne (domaines de restriction dynamic). |
| 8 | server_action |
ir.actions.server |
Déploie des scripts Python exécutés côté serveur. |
| 9 | base_automation |
base.automation |
Lie un trigger événementiel (on_write, on_create) à un script serveur. |
| 10 | cron |
ir.cron |
Programme des exécutions régulières et répétées de scripts Python. |
| 11 | view |
ir.ui.view |
Hérite/surcharge des vues standard XML ou crée des templates QWeb autonomes (ex : pages web). |
| 12 | window_action_filter |
ir.actions.act_window |
Injecte dynamiquement des filtres par défaut au niveau du contexte d'une action. |
| 13 | website_page |
website.page |
Crée une page web dynamique publique liée à un template QWeb. |
| 14 | attachment |
ir.attachment |
Stocke des fichiers bruts (CSS, SCSS, JS, OWL) sous forme de pièces jointes binaires à URL virtuelle. |
| 15 | asset |
ir.asset |
Enregistre et lie des pièces jointes à des bundles d'assets Odoo pour compilation et rendu direct. |
| 16 | record |
Modèle variable | Modifie ou crée des enregistrements de données (valeurs de champs) de façon idempotente (recherche par ID, XML-ID ou domaine). |
📖 Dictionnaire des Ressources et Exemples YAML
1. Applications (app)
Installe un module d'Odoo s'il n'est pas encore présent.
- Balises requises :
name: Nom technique du module dans le catalogue d'Odoo (ex :sale_management,crm).
- type: app
name: sale_management
2. Privilèges (privilege)
Crée un profil de privilèges applicatifs pour la sécurité (Introduit en Odoo 19). Géré avec repli transparent automatique vers category_id sur Odoo 18.
- Balises requises :
name: Identifiant local unique de la ressource.privilege_name: Nom affiché de la règle de privilège dans le menu.category_xml_id: Lien XML-ID vers la catégorie d'app Odoo parente (ex :base.module_category_all).
- type: privilege
name: contacts_privilege
privilege_name: "Contacts"
category_xml_id: "base.module_category_all"
3. Groupes de sécurité (group)
Définit un groupe d'utilisateurs avec héritage de droits d'autres groupes.
- Balises requises :
name: Identifiant local unique.group_name: Libellé utilisateur du groupe dans l'interface Odoo.
- Balises optionnelles :
privilege_name: Lien vers le privilège déclaratif créé ci-dessus.implied_xml_ids: Liste des groupes parents dont ce groupe hérite les droits (ex:base.group_userou d'autres groupes personnalisés).
- type: group
name: contacts_user_group
group_name: "Contacts / Utilisateur"
privilege_name: "contacts_privilege"
implied_xml_ids:
- "base.group_user"
4. Champs personnalisés (field)
Étend la structure des bases de données Odoo. Supporte les champs liés (related), les sélections et les champs calculés complexes (compute) persistés en base.
- Balises requises :
name: Identifiant unique.model: Nom technique du modèle Odoo à étendre (ex :res.partner).field_name: Nom technique du champ (doit obligatoirement commencer parx_).ttype: Type de données (char,float,boolean,date,selection,many2one).field_description: Libellé affiché à l'écran.
- Balises optionnelles :
relation: Modèle de liaison (requis sittype: many2one).selection: Liste de tuples au format chaîne de caractères Python (requis sittype: selection).related: Chemin du champ lié (ex :partner_id.x_first_name).compute: Code Python s'exécutant pour alimenter le champ de façon automatique.depends: Liste des champs déclenchant le calcul du compute.store: Booléen déterminant si la valeur calculée est stockée physiquement en base (trueoufalse).readonly: Empêche la modification manuelle par l'utilisateur.
# Champ de sélection simple
- type: field
name: res_partner_x_type_contrat_habituel
model: res.partner
field_name: x_type_contrat_habituel
ttype: selection
selection: "[('regie', 'Régie'), ('forfait', 'Forfait'), ('accord_cadre', 'Accord-Cadre')]"
field_description: "Type de contrat habituel"
# Champ calculé stocké en base
- type: field
name: product_template_x_productivite_heure
model: product.template
field_name: x_productivite_heure
ttype: float
field_description: "Productivité heure"
compute: |
for record in self:
record['x_productivite_heure'] = round((record.x_productivite_jour or 0.0) / 7.0, 1)
depends: "x_productivite_jour"
store: true
readonly: true
5. Droits d'accès (acl)
Définit les autorisations de lecture, d'écriture, de création et de suppression (CRUD) sur un modèle Odoo pour un groupe donné.
- Balises requises :
name: Identifiant local unique.acl_name: Nom descriptif de la règle ACL.model: Nom technique du modèle ciblé.group_name: Identifiant du groupe de sécurité personnalisé associé (ou XML-ID global).perm_read,perm_write,perm_create,perm_unlink: Valeurs booléennes (trueoufalse).
- type: acl
name: contacts_user_acl
acl_name: "Contacts User"
model: res.partner
group_name: "contacts_user_group"
perm_read: true
perm_write: true
perm_create: false
perm_unlink: false
6. Règles d'enregistrement (rule)
Fournit une sécurité dynamique au niveau de la ligne de données en utilisant les expressions de filtre Odoo (Domaines).
- Balises requises :
name: Identifiant local unique.rule_name: Titre explicite de la règle de sécurité.model: Modèle Odoo ciblé.domain_force: Expression de filtre dynamique au format chaîne (ex : structure de tuples Odoo).
- Balises optionnelles :
group_name: Groupe de sécurité limitant la portée de la règle (si absent, la règle devient globale à tous les utilisateurs).perm_read,perm_write,perm_create,perm_unlink: Portée des opérations soumises à la restriction.
- type: rule
name: crm_user_rule
rule_name: "CRM Lead / Utilisateur"
model: crm.lead
group_name: "crm_user_group"
domain_force: "['|', ('user_id', '=', user.id), ('message_partner_ids', 'in', [user.partner_id.id])]"
perm_read: true
perm_write: true
perm_create: false
perm_unlink: false
7. Actions Serveur (server_action)
Déploie un bloc de code Python à exécuter à la demande ou via une automatisation.
- Balises requises :
name: Identifiant local unique.action_name: Libellé descriptif de l'action de serveur.model: Modèle d'évaluation principal.code: Script Python complet.
- type: server_action
name: won_crm_lead_sa
action_name: "Action: Won CRM Lead on Sales Order confirmed"
model: sale.order
code: |
for record in records:
if record.opportunity_id:
record.opportunity_id.action_set_won()
8. Règles d'automatisation (base_automation)
Orchestre l'exécution d'actions de serveur à la suite de modifications en base.
- Balises requises :
name: Identifiant local unique.rule_name: Nom explicite de l'automatisation.model: Modèle de données surveillé.trigger: Type d'événement déclencheur (on_create_or_write,on_write,on_create).server_actions: Liste des actions serveur (par leur identifiant déclaratif) à lancer.
- Balises optionnelles :
trigger_fields: Liste des champs techniques dont la mise à jour déclenche la règle.
- type: base_automation
name: won_crm_lead_rule
rule_name: "Won CRM Lead on Sales Order confirmed"
model: sale.order
trigger: on_create_or_write
trigger_fields:
- state
server_actions:
- won_crm_lead_sa
9. Tâches Planifiées (cron)
Planifie l'exécution cyclique de scripts Python côté serveur. Le moteur IaC gère automatiquement la création/mise à jour synchronisée de la tâche planifiée et de son action serveur interne.
- Balises requises :
name: Identifiant local unique.cron_name: Intitulé compréhensible dans le menu des crons.model: Modèle d'exécution.code: Code Python exécuté périodiquement.
- Balises optionnelles :
interval_number: Fréquence d'exécution (défaut :1).interval_type: Unité de temps (minutes,hours,days,weeks,months).
- type: cron
name: crm_inactivity_cron
cron_name: "Cron CRM : Alerte inactivité 15j"
model: crm.lead
code: |
limit_date_start = datetime.datetime.now() - datetime.timedelta(days=16)
limit_date_end = datetime.datetime.now() - datetime.timedelta(days=15)
leads = env['crm.lead'].search([
('stage_id', 'in', [3, 8, 9]),
('write_date', '>=', limit_date_start),
('write_date', '<=', limit_date_end),
])
for record in leads:
# Code d'alerte ou de notification...
interval_number: 1
interval_type: "days"
10. Vues utilisateur (view)
Surcharge et hérite de l'architecture des vues Odoo via XPath sans réécriture complète. Le moteur IaC compile et traduit automatiquement les balises de structure de carte en fonction de la version majeure d'Odoo ciblée (par exemple, traduction dynamique bidirectionnelle entre <kanban-box> et <card> pour les vues Kanban Odoo 18 / 19).
- Balises requises :
name: Identifiant local unique.view_name: Nom d'identification technique de la vue.model: Modèle Odoo auquel la vue est rattachée.inherit_xml_id: XML-ID de la vue parente héritée (ex :base.view_partner_form).arch: Structure de modification XML / XPath.
- Balises optionnelles :
priority: Priorité de chargement de la vue (défaut :16).
- type: view
name: res_company_form_mycompany
view_name: "res.company.form.mycompany"
model: res.company
inherit_xml_id: "base.view_company_form"
priority: 16
arch: |
<data>
<xpath expr="//field[@name='company_registry']" position="after">
<field name="x_forme_juridique" string="Forme juridique"/>
<field name="x_capital_social" string="Capital social"/>
</xpath>
</data>
11. Filtres d'actions (window_action_filter)
Injecte dynamiquement des critères de recherche par défaut lors de l'ouverture de menus ou de fenêtres standard d'Odoo.
- Balises requises :
name: Identifiant unique de la ressource.xml_id: XML-ID de l'action de fenêtre parente à altérer (ex :account.action_move_out_invoice_type).filter_key: Clé de filtre de recherche par défaut (ex :search_default_late).filter_value: Valeur d'activation du filtre (généralement1pour vrai).
- type: window_action_filter
name: invoicing_out_invoice_filter_main
xml_id: "account.action_move_out_invoice_type"
filter_key: "search_default_late"
filter_value: 1
12. Modèles de Données Personnalisés (model)
Crée un nouveau modèle de données en base. Le moteur applique une auto-correction automatique pour garantir le préfixe obligatoire x_ sur les modèles personnalisés en base, et supporte les listes d'héritage standard (inherit) avec mappage automatique des fonctionnalités transverses Odoo (Chatter/messagerie via mail.thread, activités planifiées via mail.activity.mixin, etc.).
- Balises requises :
name: Identifiant unique local du modèle (auto-corrigé avec préfixex_en base de données si nécessaire).model_name: Libellé utilisateur du modèle affiché dans l'interface Odoo.
- Balises optionnelles :
inherit: Liste de modèles Odoo de type mixin dont on souhaite hériter (ex :mail.thread,mail.activity.mixin,mail.blacklist,mail.thread.sms).
- type: model
name: x_test_iac_model
model_name: "Modèle de Test IaC"
inherit:
- "mail.thread"
- "mail.activity.mixin"
13. Pages Web (website_page)
Crée et publie des pages web publiques ou privées sur le portail Odoo.
- Balises requises :
name: Identifiant local de la ressource.url: Route HTTP publique d'accès à la page (ex :/test-iac-page).view_ref: Identifiant local unique (ou XML-ID) du template QWeb décrivant la structure HTML de la page (de typeview).
- Balises optionnelles :
is_published: Rend la page immédiatement visible aux visiteurs publics (trueoufalse).website_indexed: Autorise l'indexation de la page par les moteurs de recherche (trueoufalse).
- type: website_page
name: test_iac_website_page
url: "/test-iac-page"
view_ref: test_iac_page_template
is_published: true
website_indexed: true
14. Pièces Jointes Binaires (attachment)
Permet d'héberger des fichiers arbitraires (images, PDF, ou code source comme CSS, SCSS, JS) en base de données avec des URLs virtuelles d'accès. Utile pour injecter des scripts et styles personnalisés.
- Balises requises :
name: Nom affiché du fichier dans la gestion documentaire Odoo.url: URL virtuelle relative d'accès pour appeler le fichier depuis un template ou un bundle (ex :/test_iac/static/src/scss/test_style.scss).mimetype: Type MIME du fichier (ex :text/css,text/scss,application/javascript).raw_content: Code brut ou contenu texte du fichier (le moteur l'encode automatiquement en Base64 pour le stockage binaire).
- type: attachment
name: test_iac_custom_style
url: "/test_iac/static/src/scss/test_style.scss"
mimetype: "text/scss"
raw_content: |
.my-dynamic-style {
background-color: #f9fafb !important;
border: 3px dashed #10b981 !important;
border-radius: 12px;
padding: 30px;
transition: all 0.3s ease;
&:hover {
transform: translateY(-5px);
}
}
15. Liaison d'Assets (asset)
Permet d'injecter des fichiers (téléversés au préalable via attachment) au sein des pipelines de compilation et de chargement d'Odoo en ciblant un bundle particulier (comme web.assets_backend ou web.assets_frontend).
- Balises requises :
name: Identifiant local unique de la règle d'asset.bundle: Nom technique du bundle ciblé (ex :web.assets_frontendouweb.assets_backend).path: URL virtuelle relative de la pièce jointe à charger (identique au champurlde l'attachment).
- Balises optionnelles :
directive: Instruction de traitement de l'asset (append,prepend,include,remove,replace, défaut :append).sequence: Poids ordonné de chargement du fichier (défaut :16).
- type: asset
name: test_iac_custom_asset
bundle: "web.assets_frontend"
path: "/test_iac/static/src/scss/test_style.scss"
directive: "append"
16. Modifications de valeurs de champs (record)
Permet de modifier les valeurs de champs d'enregistrements système existants (comme la société principale, les configurations par défaut, etc.) ou d'insérer de nouvelles données personnalisées de manière parfaitement idempotente.
- Balises requises :
name: Identifiant local unique de la ressource.model: Nom technique du modèle Odoo ciblé (ex :res.company,res.partner).values: Dictionnaire clé-valeur contenant les champs techniques et les valeurs à écrire.
- Balises d'identification (au moins une requise) :
xml_id: XML-ID de l'enregistrement à identifier (ex :base.main_company). Recommandé pour la portabilité.res_id: Identifiant numérique de l'enregistrement en base de données.search: Liste représentant un domaine de recherche Odoo pour identifier l'enregistrement dynamique (ex :[('name', '=', 'Mycompany')]).
# Exemple 1 : Modification d'une valeur de champ sur un enregistrement système existant
- type: record
name: update_main_company_phone
model: res.company
xml_id: "base.main_company"
values:
phone: "+33 1 23 45 67 89"
# Exemple 2 : Création (ou mise à jour) d'une nouvelle donnée personnalisée
- type: record
name: create_custom_partner
model: res.partner
values:
name: "Emmanuel"
email: "emmanuel@my-company.com"
phone: "+33 6 12 34 56 78"
comment: "Créé via Odoo IaC Engine"
---
### 17. Importation Dynamique de Données (`import`)
Permet de peupler et synchroniser des enregistrements Odoo en masse à partir de fichiers locaux CSV ou Excel (`.xlsx`), avec un mapping déclaratif de colonnes et une gestion de l'unicité pour une idempotence absolue.
* **Balises requises** :
* `name` : Identifiant local unique de la ressource.
* `model` : Nom technique du modèle Odoo ciblé (ex : `res.partner`, `product.template`).
* `file_path` : Chemin du fichier à importer sur le système local (CSV ou Excel). Les dépendances `pandas` et `openpyxl` sont incluses dans le package pour une installation automatique et transparente.
* `mapping` : Dictionnaire mappant le nom technique du champ Odoo au nom de la colonne du fichier.
* **Champs traduisibles (JSONB)** : Si un champ nécessite des traductions, vous pouvez passer un sous-dictionnaire où les clés sont les codes de langue Odoo (ex: `fr_FR`, `en_US`) et les valeurs sont les noms des colonnes contenant les traductions correspondantes.
* **Balises optionnelles** :
* `unique_by` : Nom du champ Odoo (ou liste de champs) servant de clé d'unicité. Si un enregistrement correspondant est trouvé, il est mis à jour (`write`) ; sinon, il est créé (`create`). Permet une idempotence parfaite.
```yaml
# Exemple 1 : Importation de contacts standard
- type: import
name: test_partners_import
model: res.partner
file_path: test_contacts.xlsx
unique_by: email
mapping:
name: Nom
email: Email
phone: Mobile
# Exemple 2 : Importation de produits avec traductions multiples (champs traduisibles JSONB)
- type: import
name: test_products_import
model: product.template
file_path: test_products.csv
unique_by: default_code
mapping:
default_code: "Référence"
list_price: "Prix de vente"
# Nom traduisible en Français et Anglais à partir de colonnes séparées
name:
fr_FR: "Nom Français"
en_US: "Nom Anglais"
🛡️ Sécurité, Robustesse & Validation en Phase de Compilation (Premium Enhancements)
Pour répondre aux exigences des environnements de production et des chaînes CI/CD d'entreprise, le moteur IaC ood intègre des fonctionnalités avancées de protection et de validation pré-vol :
1. Masquage des Variables Sensibles
Toutes les valeurs des attributs dont le nom de clé contient un mot clé sensible (comme password, key, token, secret, credential, private) sont automatiquement interceptées et masquées sous la forme ********** dans toutes les sorties du terminal (ood plan, ood apply, logs de compilation). Cela élimine tout risque de fuite de secrets dans les tableaux de bord CI/CD ou les fichiers de log.
2. Résolution Dynamique des relations Many2one
Lors de l'importation de données complexes via la ressource import, vous pouvez effectuer des recherches de relations Many2one à la volée. Le moteur utilise un sous-dictionnaire déclaratif pour interroger Odoo par XML-RPC et obtenir dynamiquement l'ID SQL de l'enregistrement lié (par exemple, associer un produit à sa catégorie via son nom) :
- type: import
name: import_products_with_categories
model: product.template
file_path: articles.xlsx
mapping:
default_code: "Référence"
list_price: "Prix"
# Résolution Many2one dynamique du modèle product.category
categ_id:
relation: "product.category"
search_by: "name"
column: "Nom Catégorie"
3. Contrôle de Syntaxe Python Automatique
Tous les scripts Python embarqués dans les ressources server_action, cron ou base_automation sont compilés et validés par le parseur natif Python de l'hôte lors de l'exécution de la commande ood plan. En cas d'erreur de syntaxe ou d'indentation (SyntaxError, IndentationError), la phase de planification s'interrompt immédiatement en affichant un rapport clair contenant :
- Le message d'erreur précis du compilateur.
- Le numéro de la ligne en faute.
- L'extrait de code concerné.
4. Validation Stricte des Schémas Odoo
Pendant l'étape ood plan, pour chaque ressource de type record ou import, le moteur effectue une vérification précoce ("fail-fast") en interrogeant le dictionnaire de structure (fields_get) de l'instance Odoo (avec mise en cache optimisée à un seul appel par modèle).
- Si le modèle Odoo cible n'existe pas, la planification échoue avec une erreur descriptive.
- Si un champ technique cible n'existe pas sur le modèle Odoo (ex: faute de frappe
emaiilau lieu deemail), la planification échoue immédiatement en listant la liste des champs valides disponibles pour ce modèle.
⚡ Robustesse, Vitesse & Transactionnalité d'Entreprise
Pour supporter les déploiements industriels à grande échelle et garantir une intégrité absolue de la base de données Odoo même en cas de panne réseau ou de mauvaise configuration applicative, le moteur IaC ood intègre les mécanismes avancés suivants :
1. Déploiement Parallèle Multi-threadé
Afin d'accélérer drastiquement la phase d'apply, le moteur regroupe les actions du plan par tier topologique (les ressources de même type et même action, par exemple la création en masse de 50 champs personnalisés).
- Parallélisme avec ThreadPoolExecutor : Les ressources d'un même tier sont déployées en parallèle.
- Isolation Thread-Local du Client XML-RPC : Le partage de connexions ou de proxies XML-RPC entre les threads d'exécution pouvant causer des corruptions de protocole HTTP, le client
OdooClientencapsule ses proxies et sessions dans un état thread-local (threading.local). Chaque thread dispose ainsi de sa propre connexion isolée sans surcharge mémoire. - Verrou de Sécurité sur l'État Local : Les écritures dans le fichier d'état local
ood.oodstatesont synchronisées via un verrou d'exclusion mutuelle (threading.Lock), garantissant une intégrité parfaite des données d'état. - Configuration : Le paramètre optionnel
max_workerspeut être renseigné sous la cléconnectionde votre configuration (par défaut4).
2. Audits de Sécurité Pré-vol ACL
Le déploiement IaC requiert des droits élevés d'administration (création de champs, vues, automatisations). Pour éviter qu'une exécution s'interrompe à mi-chemin à cause d'une permission manquante, le moteur effectue une vérification précoce de sécurité avant tout déploiement :
- Analyse Pré-vol des Permissions : Le moteur interroge Odoo via
check_access_rightssur tous les modèles cibles affectés par le plan (ex :ir.model.fields,ir.ui.view,ir.cron, etc.). - Exclusion Intelligente des Nouveaux Modèles : Si le plan contient la création de modèles personnalisés (de type
model), le moteur omet dynamiquement ces tables lors de la vérification pré-vol de sécurité, puisqu'elles n'existent pas encore physiquement en base. - Fail-Fast : Si une seule autorisation CRUD requise fait défaut, le déploiement s'interrompt immédiatement avec un rapport détaillé avant toute écriture en base.
3. Rollback Transactionnel sur Échec
En cas d'erreur inattendue survenant lors d'un apply (panne réseau, erreur système Odoo, validation métier bloquante) :
- Restauration Automatique de l'État : Le moteur IaC dépile la pile d'exécution dans l'ordre rigoureusement inverse de leur application.
- Annulation des Créations : Les ressources créées durant la session courante sont supprimées d'Odoo (
unlink). - Rétablissement des Mises à Jour : Pour chaque ressource mise à jour, sa configuration d'origine (préalablement sauvegardée en mémoire avant modification) est réécrite en base Odoo pour restaurer son état original exact.
- Persistance Atomique : À chaque étape du rollback, le fichier d'état local
ood.oodstateest mis à jour en temps réel pour refléter le statut physique réel de la base, évitant tout désalignement d'état en cas d'interruption abrupte.
📄 Licence
Ce projet est distribué sous licence libre GNU General Public License v3 (GPLv3). Pour plus de détails, veuillez consulter le fichier [LICENSE] situé à la racine du projet.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ood_cli-1.0.1.tar.gz.
File metadata
- Download URL: ood_cli-1.0.1.tar.gz
- Upload date:
- Size: 65.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8d948fb1a2bc3caa4a7cd740a481c772528fe519527047d1c6b5d4b5d7f5c9f
|
|
| MD5 |
4761e7b1c81ddf0528a8c0fddd497679
|
|
| BLAKE2b-256 |
1e04a838b04914138d92b8b0570b1233105769e31cfb161db6d6be45a3c978b1
|
File details
Details for the file ood_cli-1.0.1-py3-none-any.whl.
File metadata
- Download URL: ood_cli-1.0.1-py3-none-any.whl
- Upload date:
- Size: 43.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ab9f99974682e358e6caafbaa3d48f34e4a443ac417ee2b1c6653ba70e30bef
|
|
| MD5 |
e84461b964c6c39e0eccfa8056226b52
|
|
| BLAKE2b-256 |
dc80198d51c3e83515451877b4aa7b26dab4fe6a1144b5d9fe37c2af6b167cea
|