diff --git a/CHANGELOG.md b/CHANGELOG.md index 815301a..5c43055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # CHANGELOG — Set-OPS +## 2026-10-01 (61) — Une donnée restaurée l'emportait sur une règle du plan (Nextcloud) + +**Constat de l'exploitant** : dans Nextcloud, `sysadmin` n'a pas les mêmes droits chez les +deux locataires. Mesuré : administrateur (groupe `admin`) chez Technolibre, pas chez +Chezlepro — reconstruite en 40 min juste avant. + +**Ce qui devait être identique et ne l'était pas.** Les DONNÉES d'un locataire peuvent +différer d'un autre : chacune revient de son propre passé. Les RÈGLES du plan, non : « le +groupe d'habilitation est administrateur de Nextcloud » vaut pour tous. Or son effet est rangé +dans la base de Nextcloud, et le rôle l'applique AVANT de remettre la base restaurée (la remise +vient en fin de rôle, à cause du code des applications — 47) : sur la base neuve, le groupe +n'existe pas encore, l'étape passe sans rien faire, puis la base d'avant revient avec son état +d'avant. Technolibre avait reçu `admin` d'un déploiement antérieur, que la sauvegarde a gardé ; +Chezlepro jamais. La donnée décidait à la place de la règle. + +**Correction** : l'étape sort dans `admin.yml`, appelée comme avant depuis `oidc.yml`, et +REJOUÉE juste après la remise d'un Nextcloud restauré. Les autres services n'ont pas ce +défaut : Keycloak est remis avant son premier démarrage et reconfiguré ensuite ; l'annuaire +réaligne les comptes de service sur la voûte après sa remise. + ## 2026-10-01 (60) — La frontière refuse à voix haute à l'intérieur, et se tait sur l'Internet **Demande de l'exploitant** : « pour éviter des délais internes en cas de pépin, les règles qui diff --git a/roles/serveur_nextcloud/tasks/admin.yml b/roles/serveur_nextcloud/tasks/admin.yml new file mode 100644 index 0000000..f315af7 --- /dev/null +++ b/roles/serveur_nextcloud/tasks/admin.yml @@ -0,0 +1,44 @@ +--- +# LE GROUPE D'HABILITATION DEVIENT ADMINISTRATEUR DE NEXTCLOUD — sorti de `oidc.yml` le +# 2026-10-01 pour etre joue AUSSI apres la remise d'un Nextcloud restaure (`main.yml`). +# +# Dans une reconstruction, l'etape tournait AVANT la remise : sur la base neuve, ou le groupe +# n'existe pas encore, elle passait sans rien faire — puis la base d'avant revenait avec son +# etat d'avant. `sysadmin` etait administrateur chez Technolibre (verse par un deploiement +# anterieur, garde par la sauvegarde) et ne l'etait pas chez Chezlepro (jamais verse) : +# chaque reconstruction le ramenait tel quel. +# +# Les groupes projetes depuis LDAP arrivent dans Nextcloud, mais y etre membre +# ne donne aucun pouvoir : l'administration est un GROUPE NEXTCLOUD nomme +# `admin`. On y verse le groupe d'habilitation, une fois qu'il existe. +# +# Sans cela, `meta/acces.yml` restait `porte_par: aucun` et l'administration +# passait par le compte local de secours — ce qui contredit « une identite, un +# mot de passe » (2026-08-07). +- name: Verser le groupe d'administration dans le groupe `admin` de Nextcloud + ansible.builtin.shell: + executable: /bin/bash + cmd: | + set -eo pipefail + OCC="php {{ serveur_nextcloud_racine }}/occ" + G="{{ serveur_nextcloud_oidc_groupe_admin }}" + # Le groupe n'existe qu'apres la premiere connexion d'un membre : son + # absence n'est donc PAS une erreur au premier deploiement. + if ! $OCC group:list --output=json | grep -q "\"$G\""; then + echo "SETOPS_OK (groupe '$G' pas encore provisionne — a la premiere connexion)" + exit 0 + fi + CHANGED=0 + for U in $($OCC group:list --output=json | python3 -c " + import json,sys + print(' '.join((json.load(sys.stdin).get('$G') or [])))"); do + if ! $OCC group:list --output=json | python3 -c " + import json,sys + sys.exit(0 if '$U' in (json.load(sys.stdin).get('admin') or []) else 1)"; then + $OCC group:adduser admin "$U" >/dev/null && CHANGED=1 + fi + done + [ "$CHANGED" = 1 ] && echo SETOPS_CHANGED || echo SETOPS_OK + register: serveur_nextcloud_grp_admin + changed_when: "'SETOPS_CHANGED' in serveur_nextcloud_grp_admin.stdout" + when: serveur_nextcloud_oidc_groupe_admin | length > 0 diff --git a/roles/serveur_nextcloud/tasks/main.yml b/roles/serveur_nextcloud/tasks/main.yml index 4bf8ed7..a06eacd 100644 --- a/roles/serveur_nextcloud/tasks/main.yml +++ b/roles/serveur_nextcloud/tasks/main.yml @@ -93,6 +93,15 @@ - name: Etat d'une incarnation precedente (base, fichiers, configuration) ansible.builtin.import_tasks: restaurer.yml +# APRES LA REMISE, LES HABILITATIONS DU PLAN (2026-10-01) : la base restauree porte l'etat +# d'avant ; l'appartenance du groupe d'habilitation a `admin` est une regle du plan, pas un +# etat a conserver — on la rejoue sur ce qui vient d'etre remis. +- name: Habilitations du plan sur le Nextcloud restaure + ansible.builtin.include_tasks: admin.yml + when: + - serveur_nextcloud_oidc_actif | bool + - client_backup_restauration.etat | default('') == 'restaure' + - name: Assurer le repertoire des sondes de supervision ansible.builtin.file: path: /usr/local/lib/setops/sondes diff --git a/roles/serveur_nextcloud/tasks/oidc.yml b/roles/serveur_nextcloud/tasks/oidc.yml index c1288ba..5f6615c 100644 --- a/roles/serveur_nextcloud/tasks/oidc.yml +++ b/roles/serveur_nextcloud/tasks/oidc.yml @@ -50,37 +50,5 @@ changed_when: false no_log: true - # Les groupes projetes depuis LDAP arrivent dans Nextcloud, mais y etre membre - # ne donne aucun pouvoir : l'administration est un GROUPE NEXTCLOUD nomme - # `admin`. On y verse le groupe d'habilitation, une fois qu'il existe. - # - # Sans cela, `meta/acces.yml` restait `porte_par: aucun` et l'administration - # passait par le compte local de secours — ce qui contredit « une identite, un - # mot de passe » (2026-08-07). - - name: Verser le groupe d'administration dans le groupe `admin` de Nextcloud - ansible.builtin.shell: - executable: /bin/bash - cmd: | - set -eo pipefail - OCC="php {{ serveur_nextcloud_racine }}/occ" - G="{{ serveur_nextcloud_oidc_groupe_admin }}" - # Le groupe n'existe qu'apres la premiere connexion d'un membre : son - # absence n'est donc PAS une erreur au premier deploiement. - if ! $OCC group:list --output=json | grep -q "\"$G\""; then - echo "SETOPS_OK (groupe '$G' pas encore provisionne — a la premiere connexion)" - exit 0 - fi - CHANGED=0 - for U in $($OCC group:list --output=json | python3 -c " - import json,sys - print(' '.join((json.load(sys.stdin).get('$G') or [])))"); do - if ! $OCC group:list --output=json | python3 -c " - import json,sys - sys.exit(0 if '$U' in (json.load(sys.stdin).get('admin') or []) else 1)"; then - $OCC group:adduser admin "$U" >/dev/null && CHANGED=1 - fi - done - [ "$CHANGED" = 1 ] && echo SETOPS_CHANGED || echo SETOPS_OK - register: serveur_nextcloud_grp_admin - changed_when: "'SETOPS_CHANGED' in serveur_nextcloud_grp_admin.stdout" - when: serveur_nextcloud_oidc_groupe_admin | length > 0 + - name: Verser le groupe d'administration dans `admin` (voir admin.yml) + ansible.builtin.include_tasks: admin.yml